blaizejs 0.3.4 → 0.4.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.
Files changed (31) hide show
  1. package/dist/chunk-GP5NAYQS.js +11 -0
  2. package/dist/chunk-GP5NAYQS.js.map +1 -0
  3. package/dist/{chunk-EE2VJ6JY.js → chunk-LI53MJIF.js} +3 -3
  4. package/dist/chunk-LI53MJIF.js.map +1 -0
  5. package/dist/{chunk-HSLLYUVO.js → chunk-LMTJAVHX.js} +3 -3
  6. package/dist/chunk-LMTJAVHX.js.map +1 -0
  7. package/dist/{chunk-TL4GIFTB.js → chunk-N7F6OHDX.js} +3 -3
  8. package/dist/chunk-N7F6OHDX.js.map +1 -0
  9. package/dist/{chunk-VLVWNGUO.js → chunk-ORFAFXHX.js} +3 -3
  10. package/dist/chunk-ORFAFXHX.js.map +1 -0
  11. package/dist/index.cjs +9 -9
  12. package/dist/index.cjs.map +1 -1
  13. package/dist/index.d.cts +654 -139
  14. package/dist/index.d.ts +654 -139
  15. package/dist/index.js +9 -9
  16. package/dist/index.js.map +1 -1
  17. package/dist/{internal-server-error-GWBNT3OO.js → internal-server-error-DAEFNRNG.js} +3 -3
  18. package/dist/{payload-too-large-error-EBM5BNWG.js → payload-too-large-error-YO3MSQJF.js} +3 -3
  19. package/dist/{unsupported-media-type-error-YQ7GCZ32.js → unsupported-media-type-error-GW2UC37Q.js} +3 -3
  20. package/dist/{validation-error-6JDCGV2S.js → validation-error-SJTLEIZZ.js} +3 -3
  21. package/package.json +4 -4
  22. package/dist/chunk-DTDGIBMA.js +0 -11
  23. package/dist/chunk-DTDGIBMA.js.map +0 -1
  24. package/dist/chunk-EE2VJ6JY.js.map +0 -1
  25. package/dist/chunk-HSLLYUVO.js.map +0 -1
  26. package/dist/chunk-TL4GIFTB.js.map +0 -1
  27. package/dist/chunk-VLVWNGUO.js.map +0 -1
  28. /package/dist/{internal-server-error-GWBNT3OO.js.map → internal-server-error-DAEFNRNG.js.map} +0 -0
  29. /package/dist/{payload-too-large-error-EBM5BNWG.js.map → payload-too-large-error-YO3MSQJF.js.map} +0 -0
  30. /package/dist/{unsupported-media-type-error-YQ7GCZ32.js.map → unsupported-media-type-error-GW2UC37Q.js.map} +0 -0
  31. /package/dist/{validation-error-6JDCGV2S.js.map → validation-error-SJTLEIZZ.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';
@@ -706,9 +707,17 @@ interface State {
706
707
  */
707
708
  _bodyError?: BodyParseError;
708
709
  }
710
+ /**
711
+ * Services container for storing injectable services/dependencies
712
+ * Allows middleware to contribute services that are accessible throughout the request lifecycle
713
+ */
714
+ interface Services {
715
+ [key: string]: unknown;
716
+ }
709
717
  interface ContextResponse<S extends State = State> {
710
718
  raw: UnifiedResponse;
711
719
  sent: boolean;
720
+ statusCode: number;
712
721
  status: (code: number) => ContextResponse<S>;
713
722
  header: (name: string, value: string) => ContextResponse<S>;
714
723
  headers: (headers: Record<string, string>) => ContextResponse<S>;
@@ -744,8 +753,12 @@ interface ContextRequest<TBody = unknown> {
744
753
  }
745
754
  /**
746
755
  * Context object representing a request/response cycle
756
+ * @template S - Type of the state object
757
+ * @template Svc - Type of the services object
758
+ * @template TBody - Type of the request body
759
+ * @template TQuery - Type of the query parameters
747
760
  */
748
- interface Context<S extends State = State, TBody = unknown, TQuery = QueryParams> {
761
+ interface Context<S extends State = State, Svc extends Services = Services, TBody = unknown, TQuery = QueryParams> {
749
762
  /**
750
763
  * Request information
751
764
  */
@@ -761,6 +774,11 @@ interface Context<S extends State = State, TBody = unknown, TQuery = QueryParams
761
774
  * Request-scoped state for storing data during the request lifecycle
762
775
  */
763
776
  state: S;
777
+ /**
778
+ * Services container for accessing injected services/dependencies
779
+ * Populated by middleware that contribute services
780
+ */
781
+ services: Svc;
764
782
  }
765
783
  type MultipartLimits = {
766
784
  maxFileSize?: number;
@@ -777,9 +795,15 @@ interface ContextOptions {
777
795
  */
778
796
  parseBody?: boolean;
779
797
  /**
780
- * Additional state to merge into the context
798
+ * Initial state to include in the context
799
+ *
781
800
  */
782
801
  initialState?: State;
802
+ /**
803
+ * Initial services to include in the context
804
+ *
805
+ */
806
+ initialServices?: Services;
783
807
  /**
784
808
  * Limits for various body types to prevent abuse
785
809
  */
@@ -794,7 +818,7 @@ interface ContextOptions {
794
818
  /**
795
819
  * Function to get the current context from AsyncLocalStorage
796
820
  */
797
- type GetContextFn = <S extends State = State>() => Context<S> | undefined;
821
+ type GetContextFn = <S extends State = State, Svc extends Services = Services>() => Context<S, Svc> | undefined;
798
822
  /**
799
823
  * Factory function for creating a new context
800
824
  */
@@ -826,18 +850,21 @@ interface MiddlewareOptions {
826
850
  /** The middleware handler function */
827
851
  handler: MiddlewareFunction;
828
852
  /** Skip function to conditionally bypass middleware */
829
- skip?: ((ctx: Context) => boolean) | undefined;
853
+ skip?: ((ctx: Context<any, any>) => boolean) | undefined;
830
854
  /** Enable debugging for this middleware */
831
855
  debug?: boolean;
832
856
  }
833
857
  /**
834
- * Middleware type
858
+ * Middleware type with generic parameters for type-safe state and service contributions
859
+ * @template TState - Type of state this middleware contributes to the context
860
+ * @template TServices - Type of services this middleware contributes to the context
835
861
  */
836
- interface Middleware {
862
+ interface Middleware<TState = {}, TServices = {}> {
837
863
  name: string;
838
864
  execute: MiddlewareFunction;
839
865
  skip?: ((ctx: Context) => boolean) | undefined;
840
866
  debug?: boolean | undefined;
867
+ _services?: TServices;
841
868
  }
842
869
 
843
870
  /**
@@ -870,7 +897,8 @@ ED extends z.ZodType = z.ZodType<any>> {
870
897
  /**
871
898
  * Route handler function with strongly typed params and response
872
899
  */
873
- type RouteHandler<TParams = Record<string, string>, TQuery = Record<string, string | string[] | undefined>, TBody = unknown, TResponse = unknown> = (ctx: Context<State, TBody, TQuery>, params: TParams) => Promise<TResponse> | TResponse;
900
+ 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
901
+ TServices extends Services = Services> = (ctx: Context<TState, TServices, TBody, TQuery>, params: TParams) => Promise<TResponse> | TResponse;
874
902
  /**
875
903
  * Options for a route method with schema-based type inference
876
904
  */
@@ -1084,32 +1112,29 @@ interface FindRouteFilesOptions {
1084
1112
  ignore?: string[] | undefined;
1085
1113
  }
1086
1114
  /**
1087
- * GET route creator - no body schema needed
1088
- * FIXED: Default type parameters to never instead of z.ZodType<any>
1115
+ * GET route creator with state and services support
1116
+ * Now returns a higher-order function to handle generics properly
1089
1117
  */
1090
- type CreateGetRoute = <P = never, // Changed from z.ZodType<any>
1091
- Q = never, // Changed from z.ZodType<any>
1092
- R = never>(config: {
1118
+ type CreateGetRoute = <TState extends State = State, TServices extends Services = Services>() => <P = never, Q = never, R = never>(config: {
1093
1119
  schema?: {
1094
1120
  params?: P extends never ? never : P;
1095
1121
  query?: Q extends never ? never : Q;
1096
1122
  response?: R extends never ? never : R;
1097
1123
  };
1098
- handler: RouteHandler<P extends z.ZodType ? Infer<P> : Record<string, string>, Q extends z.ZodType ? Infer<Q> : QueryParams, never, [
1124
+ handler: RouteHandler<P extends z.ZodType ? Infer<P> : Record<string, string>, Q extends z.ZodType ? Infer<Q> : QueryParams, never, // GET never has body
1125
+ [
1099
1126
  R
1100
- ] extends [never] ? void : R extends z.ZodType ? Infer<R> : void>;
1127
+ ] extends [never] ? void : R extends z.ZodType ? Infer<R> : void, TState, TServices>;
1101
1128
  middleware?: Middleware[];
1102
1129
  options?: Record<string, unknown>;
1103
1130
  }) => {
1104
- GET: RouteMethodOptions<P extends never ? never : P extends z.ZodType ? P : never, Q extends never ? never : Q extends z.ZodType ? Q : never, never, // GET never has body
1105
- R extends never ? never : R extends z.ZodType ? R : never>;
1131
+ 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
1132
  path: string;
1107
1133
  };
1108
1134
  /**
1109
- * POST route creator - includes body schema
1110
- * FIXED: Default type parameters to never
1135
+ * POST route creator with state and services support
1111
1136
  */
1112
- type CreatePostRoute = <P = never, Q = never, B = never, R = never>(config: {
1137
+ type CreatePostRoute = <TState extends State = State, TServices extends Services = Services>() => <P = never, Q = never, B = never, R = never>(config: {
1113
1138
  schema?: {
1114
1139
  params?: P extends never ? never : P;
1115
1140
  query?: Q extends never ? never : Q;
@@ -1118,7 +1143,7 @@ type CreatePostRoute = <P = never, Q = never, B = never, R = never>(config: {
1118
1143
  };
1119
1144
  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
1145
  R
1121
- ] extends [never] ? void : R extends z.ZodType ? Infer<R> : void>;
1146
+ ] extends [never] ? void : R extends z.ZodType ? Infer<R> : void, TState, TServices>;
1122
1147
  middleware?: Middleware[];
1123
1148
  options?: Record<string, unknown>;
1124
1149
  }) => {
@@ -1126,10 +1151,9 @@ type CreatePostRoute = <P = never, Q = never, B = never, R = never>(config: {
1126
1151
  path: string;
1127
1152
  };
1128
1153
  /**
1129
- * PUT route creator - includes body schema
1130
- * FIXED: Default type parameters to never
1154
+ * PUT route creator with state and services support
1131
1155
  */
1132
- type CreatePutRoute = <P = never, Q = never, B = never, R = never>(config: {
1156
+ type CreatePutRoute = <TState extends State = State, TServices extends Services = Services>() => <P = never, Q = never, B = never, R = never>(config: {
1133
1157
  schema?: {
1134
1158
  params?: P extends never ? never : P;
1135
1159
  query?: Q extends never ? never : Q;
@@ -1138,7 +1162,7 @@ type CreatePutRoute = <P = never, Q = never, B = never, R = never>(config: {
1138
1162
  };
1139
1163
  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
1164
  R
1141
- ] extends [never] ? void : R extends z.ZodType ? Infer<R> : void>;
1165
+ ] extends [never] ? void : R extends z.ZodType ? Infer<R> : void, TState, TServices>;
1142
1166
  middleware?: Middleware[];
1143
1167
  options?: Record<string, unknown>;
1144
1168
  }) => {
@@ -1146,30 +1170,28 @@ type CreatePutRoute = <P = never, Q = never, B = never, R = never>(config: {
1146
1170
  path: string;
1147
1171
  };
1148
1172
  /**
1149
- * DELETE route creator - typically no body
1150
- * FIXED: Default type parameters to never
1173
+ * DELETE route creator with state and services support
1151
1174
  */
1152
- type CreateDeleteRoute = <P = never, Q = never, R = never>(config: {
1175
+ type CreateDeleteRoute = <TState extends State = State, TServices extends Services = Services>() => <P = never, Q = never, R = never>(config: {
1153
1176
  schema?: {
1154
1177
  params?: P extends never ? never : P;
1155
1178
  query?: Q extends never ? never : Q;
1156
1179
  response?: R extends never ? never : R;
1157
1180
  };
1158
- handler: RouteHandler<P extends z.ZodType ? Infer<P> : Record<string, string>, Q extends z.ZodType ? Infer<Q> : QueryParams, never, [
1181
+ handler: RouteHandler<P extends z.ZodType ? Infer<P> : Record<string, string>, Q extends z.ZodType ? Infer<Q> : QueryParams, never, // DELETE never has body
1182
+ [
1159
1183
  R
1160
- ] extends [never] ? void : R extends z.ZodType ? Infer<R> : void>;
1184
+ ] extends [never] ? void : R extends z.ZodType ? Infer<R> : void, TState, TServices>;
1161
1185
  middleware?: Middleware[];
1162
1186
  options?: Record<string, unknown>;
1163
1187
  }) => {
1164
- DELETE: RouteMethodOptions<P extends never ? never : P extends z.ZodType ? P : never, Q extends never ? never : Q extends z.ZodType ? Q : never, never, // DELETE never has body
1165
- R extends never ? never : R extends z.ZodType ? R : never>;
1188
+ 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
1189
  path: string;
1167
1190
  };
1168
1191
  /**
1169
- * PATCH route creator - includes body schema
1170
- * FIXED: Default type parameters to never
1192
+ * PATCH route creator with state and services support
1171
1193
  */
1172
- type CreatePatchRoute = <P = never, Q = never, B = never, R = never>(config: {
1194
+ type CreatePatchRoute = <TState extends State = State, TServices extends Services = Services>() => <P = never, Q = never, B = never, R = never>(config: {
1173
1195
  schema?: {
1174
1196
  params?: P extends never ? never : P;
1175
1197
  query?: Q extends never ? never : Q;
@@ -1178,7 +1200,7 @@ type CreatePatchRoute = <P = never, Q = never, B = never, R = never>(config: {
1178
1200
  };
1179
1201
  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
1202
  R
1181
- ] extends [never] ? void : R extends z.ZodType ? Infer<R> : void>;
1203
+ ] extends [never] ? void : R extends z.ZodType ? Infer<R> : void, TState, TServices>;
1182
1204
  middleware?: Middleware[];
1183
1205
  options?: Record<string, unknown>;
1184
1206
  }) => {
@@ -1186,43 +1208,41 @@ type CreatePatchRoute = <P = never, Q = never, B = never, R = never>(config: {
1186
1208
  path: string;
1187
1209
  };
1188
1210
  /**
1189
- * HEAD route creator - no body schema needed (same as GET)
1190
- * FIXED: Default type parameters to never
1211
+ * HEAD route creator with state and services support
1191
1212
  */
1192
- type CreateHeadRoute = <P = never, Q = never, R = never>(config: {
1213
+ type CreateHeadRoute = <TState extends State = State, TServices extends Services = Services>() => <P = never, Q = never, R = never>(config: {
1193
1214
  schema?: {
1194
1215
  params?: P extends never ? never : P;
1195
1216
  query?: Q extends never ? never : Q;
1196
1217
  response?: R extends never ? never : R;
1197
1218
  };
1198
- handler: RouteHandler<P extends z.ZodType ? Infer<P> : Record<string, string>, Q extends z.ZodType ? Infer<Q> : QueryParams, never, [
1219
+ handler: RouteHandler<P extends z.ZodType ? Infer<P> : Record<string, string>, Q extends z.ZodType ? Infer<Q> : QueryParams, never, // HEAD never has body
1220
+ [
1199
1221
  R
1200
- ] extends [never] ? void : R extends z.ZodType ? Infer<R> : void>;
1222
+ ] extends [never] ? void : R extends z.ZodType ? Infer<R> : void, TState, TServices>;
1201
1223
  middleware?: Middleware[];
1202
1224
  options?: Record<string, unknown>;
1203
1225
  }) => {
1204
- HEAD: RouteMethodOptions<P extends never ? never : P extends z.ZodType ? P : never, Q extends never ? never : Q extends z.ZodType ? Q : never, never, // HEAD never has body
1205
- R extends never ? never : R extends z.ZodType ? R : never>;
1226
+ 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
1227
  path: string;
1207
1228
  };
1208
1229
  /**
1209
- * OPTIONS route creator - typically no body or response schema
1210
- * FIXED: Default type parameters to never
1230
+ * OPTIONS route creator with state and services support
1211
1231
  */
1212
- type CreateOptionsRoute = <P = never, Q = never, R = never>(config: {
1232
+ type CreateOptionsRoute = <TState extends State = State, TServices extends Services = Services>() => <P = never, Q = never, R = never>(config: {
1213
1233
  schema?: {
1214
1234
  params?: P extends never ? never : P;
1215
1235
  query?: Q extends never ? never : Q;
1216
1236
  response?: R extends never ? never : R;
1217
1237
  };
1218
- handler: RouteHandler<P extends z.ZodType ? Infer<P> : Record<string, string>, Q extends z.ZodType ? Infer<Q> : QueryParams, never, [
1238
+ handler: RouteHandler<P extends z.ZodType ? Infer<P> : Record<string, string>, Q extends z.ZodType ? Infer<Q> : QueryParams, never, // OPTIONS never has body
1239
+ [
1219
1240
  R
1220
- ] extends [never] ? void : R extends z.ZodType ? Infer<R> : void>;
1241
+ ] extends [never] ? void : R extends z.ZodType ? Infer<R> : void, TState, TServices>;
1221
1242
  middleware?: Middleware[];
1222
1243
  options?: Record<string, unknown>;
1223
1244
  }) => {
1224
- OPTIONS: RouteMethodOptions<P extends never ? never : P extends z.ZodType ? P : never, Q extends never ? never : Q extends z.ZodType ? Q : never, never, // OPTIONS never has body
1225
- R extends never ? never : R extends z.ZodType ? R : never>;
1245
+ 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
1246
  path: string;
1227
1247
  };
1228
1248
 
@@ -1234,14 +1254,105 @@ declare function compose(middlewareStack: Middleware[]): MiddlewareFunction;
1234
1254
  /**
1235
1255
  * Create a middleware
1236
1256
  */
1237
- declare function create$2(handlerOrOptions: MiddlewareFunction | MiddlewareOptions): Middleware;
1257
+ declare function create$2<TState = {}, TServices = {}>(handlerOrOptions: MiddlewareFunction | MiddlewareOptions): Middleware<TState, TServices>;
1258
+ /**
1259
+ * Create a middleware that only contributes state (no services)
1260
+ * Convenience helper for state-only middleware
1261
+ *
1262
+ * @template T - Type of state to contribute
1263
+ * @param handler - Middleware function that adds state
1264
+ * @returns Middleware that contributes state only
1265
+ *
1266
+ */
1267
+ declare function stateMiddleware<T = {}>(handler: MiddlewareFunction): Middleware<T, {}>;
1268
+ /**
1269
+ * Create a middleware that only contributes services (no state)
1270
+ * Convenience helper for service-only middleware
1271
+ *
1272
+ * @template T - Type of services to contribute
1273
+ * @param handler - Middleware function that adds services
1274
+ * @returns Middleware that contributes services only
1275
+ *
1276
+ */
1277
+ declare function serviceMiddleware<T = {}>(handler: MiddlewareFunction): Middleware<{}, T>;
1278
+
1279
+ type ExtractMethod<T> = T extends {
1280
+ GET: any;
1281
+ } ? 'GET' : T extends {
1282
+ POST: any;
1283
+ } ? 'POST' : T extends {
1284
+ PUT: any;
1285
+ } ? 'PUT' : T extends {
1286
+ DELETE: any;
1287
+ } ? 'DELETE' : T extends {
1288
+ PATCH: any;
1289
+ } ? 'PATCH' : T extends {
1290
+ HEAD: any;
1291
+ } ? 'HEAD' : T extends {
1292
+ OPTIONS: any;
1293
+ } ? 'OPTIONS' : never;
1294
+ type BuildRoutesRegistry<TRoutes extends Record<string, any>> = {
1295
+ [Method in ExtractMethod<TRoutes[keyof TRoutes]> as `$${Lowercase<Method>}`]: {
1296
+ [K in keyof TRoutes as ExtractMethod<TRoutes[K]> extends Method ? K : never]: TRoutes[K];
1297
+ };
1298
+ };
1299
+ type GetRouteMethodOptions<TRoute> = TRoute extends {
1300
+ GET: infer M;
1301
+ } ? M : TRoute extends {
1302
+ POST: infer M;
1303
+ } ? M : TRoute extends {
1304
+ PUT: infer M;
1305
+ } ? M : TRoute extends {
1306
+ DELETE: infer M;
1307
+ } ? M : TRoute extends {
1308
+ PATCH: infer M;
1309
+ } ? M : TRoute extends {
1310
+ HEAD: infer M;
1311
+ } ? M : TRoute extends {
1312
+ OPTIONS: infer M;
1313
+ } ? M : never;
1314
+ type IsNever$1<T> = [T] extends [never] ? true : false;
1315
+ type BuildArgsObject<P, Q, B> = (IsNever$1<P> extends true ? {} : {
1316
+ params: Infer<P>;
1317
+ }) & (IsNever$1<Q> extends true ? {} : {
1318
+ query: Infer<Q>;
1319
+ }) & (IsNever$1<B> extends true ? {} : {
1320
+ body: Infer<B>;
1321
+ });
1322
+ type IsEmptyObject<T> = keyof T extends never ? true : false;
1323
+ type BuildArgs<P, Q, B> = IsEmptyObject<BuildArgsObject<P, Q, B>> extends true ? void : BuildArgsObject<P, Q, B>;
1324
+ type CreateClientMethod<TRoute> = GetRouteMethodOptions<TRoute> extends RouteMethodOptions<infer P, infer Q, infer B, infer R> ? BuildArgs<P, Q, B> extends void ? () => Promise<R extends z.ZodType ? Infer<R> : unknown> : (args: BuildArgs<P, Q, B>) => Promise<R extends z.ZodType ? Infer<R> : unknown> : never;
1325
+ type CreateClient<TRoutes extends Record<string, Record<string, any>>> = {
1326
+ [Method in keyof TRoutes]: {
1327
+ [RouteName in keyof TRoutes[Method]]: CreateClientMethod<TRoutes[Method][RouteName]>;
1328
+ };
1329
+ };
1330
+ interface ClientConfig {
1331
+ baseUrl: string;
1332
+ defaultHeaders?: Record<string, string>;
1333
+ timeout?: number;
1334
+ }
1335
+ interface InternalRequestArgs {
1336
+ params?: Record<string, any>;
1337
+ query?: Record<string, any>;
1338
+ body?: any;
1339
+ }
1340
+ interface RequestOptions {
1341
+ method: string;
1342
+ url: string;
1343
+ headers: Record<string, string>;
1344
+ body?: string;
1345
+ timeout: number;
1346
+ }
1238
1347
 
1239
1348
  /**
1240
- * BlaizeJS Server Module
1349
+ * BlaizeJS Server Module - Enhanced with Correlation Configuration
1241
1350
  *
1242
- * Provides the core HTTP/2 server implementation with HTTP/1.1 fallback.
1351
+ * Provides the core HTTP/2 server implementation with HTTP/1.1 fallback
1352
+ * and correlation ID tracking configuration.
1243
1353
  */
1244
1354
 
1355
+ type UnknownServer = Server<Record<string, unknown>, Record<string, unknown>>;
1245
1356
  interface Http2Options {
1246
1357
  enabled?: boolean | undefined;
1247
1358
  keyFile?: string | undefined;
@@ -1257,6 +1368,21 @@ interface StopOptions {
1257
1368
  onStopping?: () => Promise<void> | void;
1258
1369
  onStopped?: () => Promise<void> | void;
1259
1370
  }
1371
+ /**
1372
+ * Correlation ID configuration options
1373
+ */
1374
+ interface CorrelationOptions {
1375
+ /**
1376
+ * The HTTP header name to use for correlation IDs
1377
+ * @default 'x-correlation-id'
1378
+ */
1379
+ headerName?: string;
1380
+ /**
1381
+ * Custom correlation ID generator function
1382
+ * @default () => `req_${timestamp}_${random}`
1383
+ */
1384
+ generator?: () => string;
1385
+ }
1260
1386
  /**
1261
1387
  * Server options for configuring the BlaizeJS server
1262
1388
  */
@@ -1280,6 +1406,11 @@ interface ServerOptionsInput {
1280
1406
  middleware?: Middleware[];
1281
1407
  /** Plugins to register */
1282
1408
  plugins?: Plugin[];
1409
+ /**
1410
+ * Correlation ID configuration
1411
+ * @since 0.4.0
1412
+ */
1413
+ correlation?: CorrelationOptions;
1283
1414
  }
1284
1415
  /**
1285
1416
  * Configuration for a BlaizeJS server
@@ -1304,11 +1435,20 @@ interface ServerOptions {
1304
1435
  middleware?: Middleware[];
1305
1436
  /** Plugins to register */
1306
1437
  plugins?: Plugin[];
1438
+ /**
1439
+ * Correlation ID configuration
1440
+ * @since 0.4.0
1441
+ */
1442
+ correlation?: CorrelationOptions;
1307
1443
  }
1308
1444
  /**
1309
- * BlaizeJS Server instance
1445
+ * BlaizeJS Server instance with generic type accumulation
1446
+ *
1447
+ * @template TState - The accumulated state type from middleware
1448
+ * @template TServices - The accumulated services type from middleware and plugins
1449
+ *
1310
1450
  */
1311
- interface Server {
1451
+ interface Server<TState, TServices> {
1312
1452
  /** The underlying HTTP or HTTP/2 server */
1313
1453
  server: http.Server | http2.Http2Server | undefined;
1314
1454
  /** The port the server is configured to listen on */
@@ -1325,13 +1465,47 @@ interface Server {
1325
1465
  unregister: () => void;
1326
1466
  };
1327
1467
  /** Start the server and listen for connections */
1328
- listen: (port?: number, host?: string) => Promise<Server>;
1468
+ listen: (port?: number, host?: string) => Promise<Server<TState, TServices>>;
1329
1469
  /** Stop the server */
1330
1470
  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>;
1471
+ /**
1472
+ * Add global middleware to the server
1473
+ *
1474
+ * @param middleware - Single middleware or array of middleware to add
1475
+ * @returns New Server instance with accumulated types from the middleware
1476
+ *
1477
+ * @example
1478
+ * ```typescript
1479
+ * // Single middleware
1480
+ * const serverWithAuth = server.use(authMiddleware);
1481
+ * // serverWithAuth has type Server<{user: User}, {auth: AuthService}>
1482
+ *
1483
+ * // Array of middleware
1484
+ * const serverWithMiddleware = server.use([authMiddleware, loggerMiddleware]);
1485
+ * // serverWithMiddleware has type Server<{user, requestId}, {auth, logger}>
1486
+ * ```
1487
+ */
1488
+ use<MS, MSvc>(middleware: Middleware<MS, MSvc>): Server<TState & MS, TServices & MSvc>;
1489
+ use<MW extends readonly Middleware<any, any>[]>(middleware: MW): Server<TState & UnionToIntersection<ExtractMiddlewareState<MW[number]>>, TServices & UnionToIntersection<ExtractMiddlewareServices<MW[number]>>>;
1490
+ /**
1491
+ * Register a plugin with the server
1492
+ *
1493
+ * @param plugin - Single plugin or array of plugins to register
1494
+ * @returns Promise resolving to new Server instance with accumulated types
1495
+ *
1496
+ * @example
1497
+ * ```typescript
1498
+ * // Single plugin
1499
+ * const serverWithDb = await server.register(databasePlugin);
1500
+ * // serverWithDb has type Server<{}, {db: DatabaseService}>
1501
+ *
1502
+ * // Array of plugins
1503
+ * const serverWithPlugins = await server.register([dbPlugin, cachePlugin]);
1504
+ * // serverWithPlugins has type Server<{}, {db, cache}>
1505
+ * ```
1506
+ */
1507
+ register<PS, PSvc>(plugin: Plugin<PS, PSvc>): Promise<Server<TState & PS, TServices & PSvc>>;
1508
+ register<P extends readonly Plugin<any, any>[]>(plugin: P): Promise<Server<TState & UnionToIntersection<ExtractPluginState<P[number]>>, TServices & UnionToIntersection<ExtractPluginServices<P[number]>>>>;
1335
1509
  /** Access to the routing system */
1336
1510
  router: Router;
1337
1511
  /** Context storage system */
@@ -1358,11 +1532,11 @@ interface PluginOptions<_T = any> {
1358
1532
  */
1359
1533
  interface PluginHooks {
1360
1534
  /** Called when the plugin is registered */
1361
- register: (app: Server) => void | Promise<void>;
1535
+ register: (app: Server<any, any>) => void | Promise<void>;
1362
1536
  /** Called when the server is initialized */
1363
- initialize?: (app?: Server) => void | Promise<void>;
1537
+ initialize?: (app?: Server<any, any>) => void | Promise<void>;
1364
1538
  /** Called when the server is terminated */
1365
- terminate?: (app?: Server) => void | Promise<void>;
1539
+ terminate?: (app?: Server<any, any>) => void | Promise<void>;
1366
1540
  /** Called when the server starts */
1367
1541
  onServerStart?: (server: any) => void | Promise<void>;
1368
1542
  /** Called when the server stops */
@@ -1371,21 +1545,27 @@ interface PluginHooks {
1371
1545
  /**
1372
1546
  * Plugin interface
1373
1547
  */
1374
- interface Plugin extends PluginHooks {
1548
+ interface Plugin<TState = {}, TServices = {}> extends PluginHooks {
1375
1549
  /** Plugin name */
1376
1550
  name: string;
1377
1551
  /** Plugin version */
1378
1552
  version: string;
1553
+ /**
1554
+ * Type carriers for compile-time type information
1555
+ * These are never used at runtime but allow TypeScript to track types
1556
+ */
1557
+ _state?: TState;
1558
+ _services?: TServices;
1379
1559
  }
1380
1560
  /**
1381
1561
  * Plugin factory function
1382
1562
  */
1383
- type PluginFactory<T = any> = (options?: T) => Plugin;
1563
+ type PluginFactory<T = any, TState extends Record<string, unknown> = {}, TServices extends Record<string, unknown> = {}> = (options?: T) => Plugin<TState, TServices>;
1384
1564
  interface PluginLifecycleManager {
1385
- initializePlugins(server: Server): Promise<void>;
1386
- terminatePlugins(server: Server): Promise<void>;
1387
- onServerStart(server: Server, httpServer: any): Promise<void>;
1388
- onServerStop(server: Server, httpServer: any): Promise<void>;
1565
+ initializePlugins(server: Server<any, any>): Promise<void>;
1566
+ terminatePlugins(server: Server<any, any>): Promise<void>;
1567
+ onServerStart(server: Server<any, any>, httpServer: any): Promise<void>;
1568
+ onServerStop(server: Server<any, any>, httpServer: any): Promise<void>;
1389
1569
  }
1390
1570
  interface PluginLifecycleOptions {
1391
1571
  /** Continue initialization even if a plugin fails */
@@ -1396,10 +1576,253 @@ interface PluginLifecycleOptions {
1396
1576
  onError?: (plugin: Plugin, phase: string, error: Error) => void;
1397
1577
  }
1398
1578
 
1579
+ /**
1580
+ * Type composition utilities for extracting and composing middleware type contributions
1581
+ * @module composition
1582
+ * @since v0.4.0
1583
+ */
1584
+
1585
+ /**
1586
+ * Extracts the State type contribution from a middleware
1587
+ * @template T - The middleware type to extract from
1588
+ * @returns The state type if present, empty object otherwise
1589
+ */
1590
+ type ExtractMiddlewareState<T> = T extends Middleware<infer S, any> ? S : {};
1591
+ /**
1592
+ * Extracts the State type contribution from a plugin
1593
+ * @template T - The plugin type to extract from
1594
+ * @returns The state type if present, empty object otherwise
1595
+ */
1596
+ type ExtractPluginState<T> = T extends Plugin<infer S, any> ? S : {};
1597
+ /**
1598
+ * Extracts the Services type contribution from a middleware
1599
+ * @template T - The middleware type to extract from
1600
+ * @returns The services type if present, empty object otherwise
1601
+ */
1602
+ type ExtractMiddlewareServices<T> = T extends Middleware<any, infer S> ? S : {};
1603
+ /**
1604
+ * Extracts the Services type contribution from a plugin
1605
+ * @template T - The plugin type to extract from
1606
+ * @returns The services type if present, empty object otherwise
1607
+ */
1608
+ type ExtractPluginServices<T> = T extends Plugin<any, infer S> ? S : {};
1609
+ /**
1610
+ * Utility type to convert a union type to an intersection type
1611
+ * This is the magic that allows us to compose multiple middleware contributions
1612
+ *
1613
+ * @example
1614
+ * type U = { a: string } | { b: number }
1615
+ * type I = UnionToIntersection<U> // { a: string } & { b: number }
1616
+ *
1617
+ */
1618
+ type UnionToIntersection<U> = (U extends any ? (k: U) => void : never) extends (k: infer I) => void ? I : never;
1619
+ /**
1620
+ * Composes state contributions from an array of middleware
1621
+ * Merges all state types into a single intersection type
1622
+ *
1623
+ * @template T - ReadonlyArray of Middleware
1624
+ * @returns Intersection of all state contributions
1625
+ *
1626
+ * @example
1627
+ * const middlewares = [authMiddleware, loggerMiddleware] as const;
1628
+ * type ComposedState = ComposeStates<typeof middlewares>;
1629
+ * // Result: { user: User } & { requestId: string }
1630
+ */
1631
+ type ComposeMiddlewareStates<T extends ReadonlyArray<Middleware>> = T extends readonly [] ? {} : UnionToIntersection<ExtractMiddlewareState<T[number]>>;
1632
+ /**
1633
+ * Composes state contributions from an array of plugins
1634
+ * Merges all state types into a single intersection type
1635
+ *
1636
+ * @template T - ReadonlyArray of Plugin
1637
+ * @returns Intersection of all state contributions
1638
+ *
1639
+ * @example
1640
+ * const plugins = [authPlugin, dbPlugin] as const;
1641
+ * type ComposedState = ComposePluginStates<typeof plugins>;
1642
+ * // Result: { config: AuthConfig } & { dbConnected: boolean }
1643
+ */
1644
+ type ComposePluginStates<T extends ReadonlyArray<Plugin<any, any>>> = T extends readonly [] ? {} : UnionToIntersection<ExtractPluginState<T[number]>>;
1645
+ /**
1646
+ * Composes service contributions from an array of middleware
1647
+ * Merges all service types into a single intersection type
1648
+ *
1649
+ * @template T - ReadonlyArray of Middleware
1650
+ * @returns Intersection of all service contributions
1651
+ *
1652
+ * @example
1653
+ * const middlewares = [dbMiddleware, cacheMiddleware] as const;
1654
+ * type ComposedServices = ComposeServices<typeof middlewares>;
1655
+ * // Result: { db: Database } & { cache: Cache }
1656
+ */
1657
+ type ComposeMiddlewareServices<T extends ReadonlyArray<Middleware>> = T extends readonly [] ? {} : UnionToIntersection<ExtractMiddlewareServices<T[number]>>;
1658
+ /**
1659
+ * Composes service contributions from an array of plugins
1660
+ * Merges all service types into a single intersection type
1661
+ *
1662
+ * @template T - ReadonlyArray of Plugin
1663
+ * @returns Intersection of all service contributions
1664
+ *
1665
+ * @example
1666
+ * const plugins = [dbPlugin, cachePlugin] as const;
1667
+ * type ComposedServices = ComposePluginServices<typeof plugins>;
1668
+ * // Result: { db: Database } & { cache: Cache }
1669
+ */
1670
+ type ComposePluginServices<T extends ReadonlyArray<Plugin<any, any>>> = T extends readonly [] ? {} : UnionToIntersection<ExtractPluginServices<T[number]>>;
1671
+ /**
1672
+ * Safe version of ExtractState that handles edge cases
1673
+ * @template T - The middleware type to extract from
1674
+ * @returns The state type, handling never/any/unknown gracefully
1675
+ */
1676
+ type SafeExtractMiddlewareState<T> = IsNever<T> extends true ? {} : IsAny<T> extends true ? {} : T extends Middleware<infer S, any> ? unknown extends S ? {} : S : {};
1677
+ /**
1678
+ * Safe version of ExtractPluginState that handles edge cases
1679
+ * @template T - The plugin type to extract from
1680
+ * @returns The state type, handling never/any/unknown gracefully
1681
+ */
1682
+ type SafeExtractPluginState<T> = IsNever<T> extends true ? {} : IsAny<T> extends true ? {} : T extends Plugin<infer S, any> ? unknown extends S ? {} : S : {};
1683
+ /**
1684
+ * Safe version of ExtractServices that handles edge cases
1685
+ * @template T - The middleware type to extract from
1686
+ * @returns The services type, handling never/any/unknown gracefully
1687
+ */
1688
+ type SafeExtractMiddlewareServices<T> = IsNever<T> extends true ? {} : IsAny<T> extends true ? {} : T extends Middleware<any, infer S> ? unknown extends S ? {} : S : {};
1689
+ /**
1690
+ * Safe version of ExtractPluginServices that handles edge cases
1691
+ * @template T - The plugin type to extract from
1692
+ * @returns The services type, handling never/any/unknown gracefully
1693
+ */
1694
+ type SafeExtractPluginServices<T> = IsNever<T> extends true ? {} : IsAny<T> extends true ? {} : T extends Plugin<any, infer S> ? unknown extends S ? {} : S : {};
1695
+ /**
1696
+ * Composes state with better edge case handling
1697
+ * @template T - ReadonlyArray of Middleware
1698
+ * @returns Safely composed state types
1699
+ */
1700
+ 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]>>;
1701
+ /**
1702
+ * Composes plugin state with better edge case handling
1703
+ * @template T - ReadonlyArray of Plugin
1704
+ * @returns Safely composed state types
1705
+ */
1706
+ 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]>>;
1707
+ /**
1708
+ * Composes services with better edge case handling
1709
+ * @template T - ReadonlyArray of Middleware
1710
+ * @returns Safely composed service types
1711
+ */
1712
+ 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]>>;
1713
+ /**
1714
+ * Composes plugin services with better edge case handling
1715
+ * @template T - ReadonlyArray of Plugin
1716
+ * @returns Safely composed service types
1717
+ */
1718
+ 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]>>;
1719
+ /**
1720
+ * Utility to merge two state types
1721
+ * Handles conflicts by using the rightmost (latest) type
1722
+ *
1723
+ * @template A - First state type
1724
+ * @template B - Second state type
1725
+ * @returns Merged state with B taking precedence
1726
+ */
1727
+ type MergeStates<A, B> = Omit<A, keyof B> & B;
1728
+ /**
1729
+ * Utility to merge two service types
1730
+ * Handles conflicts by using the rightmost (latest) type
1731
+ *
1732
+ * @template A - First services type
1733
+ * @template B - Second services type
1734
+ * @returns Merged services with B taking precedence
1735
+ */
1736
+ type MergeServices<A, B> = Omit<A, keyof B> & B;
1737
+ /**
1738
+ * Extract both state and services from a middleware at once
1739
+ * @template T - The middleware type
1740
+ * @returns Object with state and services types
1741
+ */
1742
+ type ExtractMiddlewareTypes<T> = {
1743
+ state: ExtractMiddlewareState<T>;
1744
+ services: ExtractMiddlewareServices<T>;
1745
+ };
1746
+ /**
1747
+ * Extract both state and services from a plugin at once
1748
+ * @template T - The plugin type
1749
+ * @returns Object with state and services types
1750
+ */
1751
+ type ExtractPluginTypes<T> = {
1752
+ state: ExtractPluginState<T>;
1753
+ services: ExtractPluginServices<T>;
1754
+ };
1755
+ /**
1756
+ * Compose both state and services from middleware array at once
1757
+ * @template T - ReadonlyArray of Middleware
1758
+ * @returns Object with composed state and services
1759
+ */
1760
+ type ComposeMiddlewareTypes<T extends ReadonlyArray<Middleware>> = {
1761
+ state: ComposeMiddlewareStates<T>;
1762
+ services: ComposeMiddlewareServices<T>;
1763
+ };
1764
+ /**
1765
+ * Compose both state and services from plugin array at once
1766
+ * @template T - ReadonlyArray of Plugin
1767
+ * @returns Object with composed state and services
1768
+ */
1769
+ type ComposePluginTypes<T extends ReadonlyArray<Plugin<any, any>>> = {
1770
+ state: ComposePluginStates<T>;
1771
+ services: ComposePluginServices<T>;
1772
+ };
1773
+ /**
1774
+ * Type guard to check if a value is a Middleware
1775
+ * @param value - Value to check
1776
+ * @returns True if value is a Middleware
1777
+ */
1778
+ declare function isMiddleware(value: unknown): value is Middleware;
1779
+ /**
1780
+ * Type guard to check if a value is a Plugin
1781
+ * @param value - Value to check
1782
+ * @returns True if value is a Plugin
1783
+ */
1784
+ declare function isPlugin(value: unknown): value is Plugin;
1785
+ /**
1786
+ * Type helper for middleware arrays
1787
+ * Ensures proper readonly array typing for composition
1788
+ *
1789
+ * @example
1790
+ * const middlewares = asMiddlewareArray([auth, logger, cache]);
1791
+ * type State = ComposeStates<typeof middlewares>;
1792
+ */
1793
+ declare function asMiddlewareArray<T extends ReadonlyArray<Middleware>>(middlewares: T): T;
1794
+ /**
1795
+ * Type helper for plugin arrays
1796
+ * Ensures proper readonly array typing for composition
1797
+ *
1798
+ * @example
1799
+ * const plugins = asPluginArray([dbPlugin, cachePlugin]);
1800
+ * type Services = ComposePluginServices<typeof plugins>;
1801
+ */
1802
+ declare function asPluginArray<T extends ReadonlyArray<Plugin<any, any>>>(plugins: T): T;
1803
+ /**
1804
+ * Create a typed middleware array with inferred types
1805
+ * Useful for getting proper const assertions
1806
+ *
1807
+ * @example
1808
+ * const middlewares = createMiddlewareArray(auth, logger, cache);
1809
+ * type State = ComposeStates<typeof middlewares>;
1810
+ */
1811
+ declare function createMiddlewareArray<T extends ReadonlyArray<Middleware>>(...middlewares: T): T;
1812
+ /**
1813
+ * Create a typed plugin array with inferred types
1814
+ * Useful for getting proper const assertions
1815
+ *
1816
+ * @example
1817
+ * const plugins = createPluginArray(dbPlugin, cachePlugin);
1818
+ * type Services = ComposePluginServices<typeof plugins>;
1819
+ */
1820
+ declare function createPluginArray<T extends ReadonlyArray<Plugin<any, any>>>(...plugins: T): T;
1821
+
1399
1822
  /**
1400
1823
  * Create a plugin with the given name, version, and setup function
1401
1824
  */
1402
- declare function create$1<T = any>(name: string, version: string, setup: (app: Server, options: T) => void | Partial<PluginHooks> | Promise<void> | Promise<Partial<PluginHooks>>, defaultOptions?: Partial<T>): PluginFactory<T>;
1825
+ 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>;
1403
1826
 
1404
1827
  /**
1405
1828
  * Create a GET route
@@ -1430,80 +1853,161 @@ declare const createHeadRoute: CreateHeadRoute;
1430
1853
  * Create an OPTIONS route (same signature as GET - no body)
1431
1854
  */
1432
1855
  declare const createOptionsRoute: CreateOptionsRoute;
1433
-
1434
1856
  /**
1435
- * Creates a BlaizeJS server instance
1857
+ * Factory that creates all route methods with consistent types
1858
+ * This is the RECOMMENDED approach for most applications
1859
+ *
1860
+ * Usage in server.ts:
1861
+ * ```typescript
1862
+ * export const route = createRouteFactory<AppState, AppServices>();
1863
+ * ```
1864
+ *
1865
+ * Usage in route files:
1866
+ * ```typescript
1867
+ * import { route } from '../server';
1868
+ *
1869
+ * export const GET = route.get({
1870
+ * handler: async (ctx) => {
1871
+ * // ctx.state and ctx.services are fully typed!
1872
+ * }
1873
+ * });
1874
+ * ```
1436
1875
  */
1437
- declare function create(options?: ServerOptionsInput): Server;
1438
-
1439
- type ExtractMethod<T> = T extends {
1440
- GET: any;
1441
- } ? 'GET' : T extends {
1442
- POST: any;
1443
- } ? 'POST' : T extends {
1444
- PUT: any;
1445
- } ? 'PUT' : T extends {
1446
- DELETE: any;
1447
- } ? 'DELETE' : T extends {
1448
- PATCH: any;
1449
- } ? 'PATCH' : T extends {
1450
- HEAD: any;
1451
- } ? 'HEAD' : T extends {
1452
- OPTIONS: any;
1453
- } ? 'OPTIONS' : never;
1454
- type BuildRoutesRegistry<TRoutes extends Record<string, any>> = {
1455
- [Method in ExtractMethod<TRoutes[keyof TRoutes]> as `$${Lowercase<Method>}`]: {
1456
- [K in keyof TRoutes as ExtractMethod<TRoutes[K]> extends Method ? K : never]: TRoutes[K];
1876
+ declare function createRouteFactory<TState extends State = State, TServices extends Services = Services>(): {
1877
+ readonly get: <P = never, Q = never, R = never>(config: {
1878
+ schema?: {
1879
+ params?: (P extends never ? never : P) | undefined;
1880
+ query?: (Q extends never ? never : Q) | undefined;
1881
+ response?: (R extends never ? never : R) | undefined;
1882
+ } | undefined;
1883
+ 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>;
1884
+ middleware?: Middleware[];
1885
+ options?: Record<string, unknown>;
1886
+ }) => {
1887
+ 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>>;
1888
+ path: string;
1457
1889
  };
1458
- };
1459
- type GetRouteMethodOptions<TRoute> = TRoute extends {
1460
- GET: infer M;
1461
- } ? M : TRoute extends {
1462
- POST: infer M;
1463
- } ? M : TRoute extends {
1464
- PUT: infer M;
1465
- } ? M : TRoute extends {
1466
- DELETE: infer M;
1467
- } ? M : TRoute extends {
1468
- PATCH: infer M;
1469
- } ? M : TRoute extends {
1470
- HEAD: infer M;
1471
- } ? M : TRoute extends {
1472
- OPTIONS: infer M;
1473
- } ? M : never;
1474
- type IsNever<T> = [T] extends [never] ? true : false;
1475
- type BuildArgsObject<P, Q, B> = (IsNever<P> extends true ? {} : {
1476
- params: Infer<P>;
1477
- }) & (IsNever<Q> extends true ? {} : {
1478
- query: Infer<Q>;
1479
- }) & (IsNever<B> extends true ? {} : {
1480
- body: Infer<B>;
1481
- });
1482
- type IsEmptyObject<T> = keyof T extends never ? true : false;
1483
- type BuildArgs<P, Q, B> = IsEmptyObject<BuildArgsObject<P, Q, B>> extends true ? void : BuildArgsObject<P, Q, B>;
1484
- type CreateClientMethod<TRoute> = GetRouteMethodOptions<TRoute> extends RouteMethodOptions<infer P, infer Q, infer B, infer R> ? BuildArgs<P, Q, B> extends void ? () => Promise<R extends z.ZodType ? Infer<R> : unknown> : (args: BuildArgs<P, Q, B>) => Promise<R extends z.ZodType ? Infer<R> : unknown> : never;
1485
- type CreateClient<TRoutes extends Record<string, Record<string, any>>> = {
1486
- [Method in keyof TRoutes]: {
1487
- [RouteName in keyof TRoutes[Method]]: CreateClientMethod<TRoutes[Method][RouteName]>;
1890
+ readonly post: <P = never, Q = never, B = never, R = never>(config: {
1891
+ schema?: {
1892
+ params?: (P extends never ? never : P) | undefined;
1893
+ query?: (Q extends never ? never : Q) | undefined;
1894
+ body?: (B extends never ? never : B) | undefined;
1895
+ response?: (R extends never ? never : R) | undefined;
1896
+ } | undefined;
1897
+ 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>;
1898
+ middleware?: Middleware[];
1899
+ options?: Record<string, unknown>;
1900
+ }) => {
1901
+ 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>>;
1902
+ path: string;
1903
+ };
1904
+ readonly put: <P = never, Q = never, B = never, R = never>(config: {
1905
+ schema?: {
1906
+ params?: (P extends never ? never : P) | undefined;
1907
+ query?: (Q extends never ? never : Q) | undefined;
1908
+ body?: (B extends never ? never : B) | undefined;
1909
+ response?: (R extends never ? never : R) | undefined;
1910
+ } | undefined;
1911
+ 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>;
1912
+ middleware?: Middleware[];
1913
+ options?: Record<string, unknown>;
1914
+ }) => {
1915
+ 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>>;
1916
+ path: string;
1917
+ };
1918
+ readonly delete: <P = never, Q = never, R = never>(config: {
1919
+ schema?: {
1920
+ params?: (P extends never ? never : P) | undefined;
1921
+ query?: (Q extends never ? never : Q) | undefined;
1922
+ response?: (R extends never ? never : R) | undefined;
1923
+ } | undefined;
1924
+ 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>;
1925
+ middleware?: Middleware[];
1926
+ options?: Record<string, unknown>;
1927
+ }) => {
1928
+ 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>>;
1929
+ path: string;
1930
+ };
1931
+ readonly patch: <P = never, Q = never, B = never, R = never>(config: {
1932
+ schema?: {
1933
+ params?: (P extends never ? never : P) | undefined;
1934
+ query?: (Q extends never ? never : Q) | undefined;
1935
+ body?: (B extends never ? never : B) | undefined;
1936
+ response?: (R extends never ? never : R) | undefined;
1937
+ } | undefined;
1938
+ 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>;
1939
+ middleware?: Middleware[];
1940
+ options?: Record<string, unknown>;
1941
+ }) => {
1942
+ 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>>;
1943
+ path: string;
1944
+ };
1945
+ readonly head: <P = never, Q = never, R = never>(config: {
1946
+ schema?: {
1947
+ params?: (P extends never ? never : P) | undefined;
1948
+ query?: (Q extends never ? never : Q) | undefined;
1949
+ response?: (R extends never ? never : R) | undefined;
1950
+ } | undefined;
1951
+ 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>;
1952
+ middleware?: Middleware[];
1953
+ options?: Record<string, unknown>;
1954
+ }) => {
1955
+ 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>>;
1956
+ path: string;
1957
+ };
1958
+ readonly options: <P = never, Q = never, R = never>(config: {
1959
+ schema?: {
1960
+ params?: (P extends never ? never : P) | undefined;
1961
+ query?: (Q extends never ? never : Q) | undefined;
1962
+ response?: (R extends never ? never : R) | undefined;
1963
+ } | undefined;
1964
+ 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>;
1965
+ middleware?: Middleware[];
1966
+ options?: Record<string, unknown>;
1967
+ }) => {
1968
+ 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>>;
1969
+ path: string;
1488
1970
  };
1489
1971
  };
1490
- interface ClientConfig {
1491
- baseUrl: string;
1492
- defaultHeaders?: Record<string, string>;
1493
- timeout?: number;
1494
- }
1495
- interface InternalRequestArgs {
1496
- params?: Record<string, any>;
1497
- query?: Record<string, any>;
1498
- body?: any;
1499
- }
1500
- interface RequestOptions {
1501
- method: string;
1502
- url: string;
1503
- headers: Record<string, string>;
1504
- body?: string;
1505
- timeout: number;
1506
- }
1972
+
1973
+ /**
1974
+ * Creates a BlaizeJS server instance
1975
+ */
1976
+ declare function create<const TMw extends readonly Middleware<any, any>[] = [], const TP extends readonly Plugin<any, any>[] = []>(options?: ServerOptionsInput & {
1977
+ middleware?: TMw;
1978
+ plugins?: TP;
1979
+ }): Server<ComposeMiddlewareStates<TMw> & ComposePluginStates<TP>, ComposeMiddlewareServices<TMw> & ComposePluginServices<TP>>;
1980
+
1981
+ /**
1982
+ * Type inference utilities for BlaizeJS
1983
+ * Minimal set of utilities needed for type-safe routing
1984
+ */
1985
+
1986
+ /**
1987
+ * Infers the context type from a server instance
1988
+ *
1989
+ * @example
1990
+ * ```typescript
1991
+ * const server = createServer().use(authMiddleware);
1992
+ * type AppContext = InferContext<typeof server>;
1993
+ * ```
1994
+ */
1995
+ 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>;
1996
+ /**
1997
+ * Runtime helper that provides type hints for development
1998
+ * Returns an empty object but gives TypeScript the correct context type
1999
+ *
2000
+ * @param _server - The server instance (not used at runtime)
2001
+ * @returns An empty object typed as the server's context
2002
+ */
2003
+ declare function inferContext<TState extends State, TServices extends Services>(_server: Server<TState, TServices>): InferContext<Server<TState, TServices>>;
2004
+
2005
+ /**
2006
+ * Gets the current correlation ID from AsyncLocalStorage
2007
+ *
2008
+ * @returns The current correlation ID, or 'unknown' if none is set
2009
+ */
2010
+ declare function getCorrelationId(): string;
1507
2011
 
1508
2012
  /**
1509
2013
  * ValidationError class for request validation failures
@@ -1822,6 +2326,7 @@ declare class UnprocessableEntityError extends BlaizeError {
1822
2326
  declare const VERSION = "0.1.0";
1823
2327
  declare const ServerAPI: {
1824
2328
  createServer: typeof create;
2329
+ inferContext: typeof inferContext;
1825
2330
  };
1826
2331
  declare const RouterAPI: {
1827
2332
  createDeleteRoute: CreateDeleteRoute;
@@ -1831,9 +2336,12 @@ declare const RouterAPI: {
1831
2336
  createPatchRoute: CreatePatchRoute;
1832
2337
  createPostRoute: CreatePostRoute;
1833
2338
  createPutRoute: CreatePutRoute;
2339
+ createRouteFactory: typeof createRouteFactory;
1834
2340
  };
1835
2341
  declare const MiddlewareAPI: {
1836
2342
  createMiddleware: typeof create$2;
2343
+ createServiceMiddleware: typeof serviceMiddleware;
2344
+ createStateMiddleware: typeof stateMiddleware;
1837
2345
  compose: typeof compose;
1838
2346
  };
1839
2347
  declare const PluginsAPI: {
@@ -1843,9 +2351,13 @@ declare const PluginsAPI: {
1843
2351
  declare const Blaize: {
1844
2352
  createServer: typeof create;
1845
2353
  createMiddleware: typeof create$2;
2354
+ createServiceMiddleware: typeof serviceMiddleware;
2355
+ createStateMiddleware: typeof stateMiddleware;
1846
2356
  createPlugin: typeof create$1;
2357
+ getCorrelationId: typeof getCorrelationId;
1847
2358
  Server: {
1848
2359
  createServer: typeof create;
2360
+ inferContext: typeof inferContext;
1849
2361
  };
1850
2362
  Router: {
1851
2363
  createDeleteRoute: CreateDeleteRoute;
@@ -1855,9 +2367,12 @@ declare const Blaize: {
1855
2367
  createPatchRoute: CreatePatchRoute;
1856
2368
  createPostRoute: CreatePostRoute;
1857
2369
  createPutRoute: CreatePutRoute;
2370
+ createRouteFactory: typeof createRouteFactory;
1858
2371
  };
1859
2372
  Middleware: {
1860
2373
  createMiddleware: typeof create$2;
2374
+ createServiceMiddleware: typeof serviceMiddleware;
2375
+ createStateMiddleware: typeof stateMiddleware;
1861
2376
  compose: typeof compose;
1862
2377
  };
1863
2378
  Plugins: {
@@ -1866,4 +2381,4 @@ declare const Blaize: {
1866
2381
  VERSION: string;
1867
2382
  };
1868
2383
 
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 };
2384
+ export { Blaize, BlaizeError, type BlaizeErrorResponse, type BodyParseError, type BuildRoutesRegistry, type ClientConfig, type ComposeMiddlewareServices, type ComposeMiddlewareStates, type ComposeMiddlewareTypes, type ComposePluginServices, type ComposePluginStates, type ComposePluginTypes, ConflictError, type ConflictErrorDetails, type Context, type ContextOptions, type ContextRequest, type ContextResponse, type CorrelationOptions, 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 ExtractMiddlewareServices, type ExtractMiddlewareState, type ExtractMiddlewareTypes, type ExtractPluginServices, type ExtractPluginState, type ExtractPluginTypes, type FileCache, type FindRouteFilesOptions, ForbiddenError, type ForbiddenErrorDetails, type GetContextFn, 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 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 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 StreamOptions, type TimeoutErrorContext, 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 };