balda 0.0.61 → 0.0.63

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/lib/index.d.cts CHANGED
@@ -349,6 +349,12 @@ declare class Request<Params extends Record<string, string> = Record<string, str
349
349
  file(fieldName: string): FormFile | null;
350
350
  get cookies(): Record<string, string>;
351
351
  set cookies(value: Record<string, string>);
352
+ /**
353
+ * Returns cookies when the cookie middleware has populated them, otherwise undefined.
354
+ * Useful for compatibility layers that should not throw when cookies are unavailable.
355
+ * @internal
356
+ */
357
+ getOptionalCookies(): Record<string, string> | undefined;
352
358
  /**
353
359
  * The cookie of the request.
354
360
  * @cookie middleware is required
@@ -362,6 +368,12 @@ declare class Request<Params extends Record<string, string> = Record<string, str
362
368
  timeout?: boolean;
363
369
  get session(): Record<string, any> | undefined;
364
370
  set session(value: Record<string, any> | undefined);
371
+ /**
372
+ * Returns session data when the session middleware has populated it, otherwise undefined.
373
+ * Useful for compatibility layers that should not throw when sessions are unavailable.
374
+ * @internal
375
+ */
376
+ getOptionalSession(): Record<string, any> | undefined;
365
377
  /**
366
378
  * Shared throwing functions to avoid per-instance closure allocation.
367
379
  * @internal
@@ -1638,6 +1650,34 @@ declare class GraphQL {
1638
1650
  private ensureTypeDefsArray;
1639
1651
  }
1640
1652
 
1653
+ declare class MockResponse<T = any> {
1654
+ readonly response: Response$1;
1655
+ constructor(response: Response$1);
1656
+ body(): T;
1657
+ statusCode(): number;
1658
+ headers(): Record<string, string>;
1659
+ cookies(): Record<string, string>;
1660
+ assertStatus(status: number): this;
1661
+ assertHeader(header: string, value: string): this;
1662
+ assertHeaderExists(header: string): this;
1663
+ assertHeaderNotExists(header: string): this;
1664
+ assertCookie(name: string, value: string): this;
1665
+ assertCookieExists(name: string): this;
1666
+ assertCookieNotExists(name: string): this;
1667
+ assertBodySubset(subset: Partial<T>): this;
1668
+ assertBodyDeepEqual(expected: T): this;
1669
+ assertBodyNotSubset(subset: Partial<T>): this;
1670
+ assertBodyNotDeepEqual(expected: T): this;
1671
+ assertCustom(assertion: (response: Response$1) => void): this;
1672
+ private assertSubset;
1673
+ private assertDeepEqual;
1674
+ private assertNotSubset;
1675
+ private assertNotDeepEqual;
1676
+ private assertArraySubset;
1677
+ private assertArrayDeepEqual;
1678
+ private isObject;
1679
+ }
1680
+
1641
1681
  declare class NativeFs {
1642
1682
  glob(...args: Parameters<typeof glob>): Promise<string[]>;
1643
1683
  mkdir(path: string, options?: {
@@ -1976,6 +2016,7 @@ declare class Server<H extends NodeHttpClient = NodeHttpClient> implements Serve
1976
2016
  isListening: boolean;
1977
2017
  isProduction: boolean;
1978
2018
  graphql: GraphQL;
2019
+ readonly inject: InjectFunction;
1979
2020
  /**
1980
2021
  * The constructor for the server
1981
2022
  * @warning Routes will only be defined after calling the `listen` method so you're free to define middlewares before calling it
@@ -2043,7 +2084,9 @@ declare class Server<H extends NodeHttpClient = NodeHttpClient> implements Serve
2043
2084
  * @returns A promise that resolves when the server is disconnected
2044
2085
  */
2045
2086
  disconnect(): Promise<void>;
2046
- getMockServer(options?: Pick<ServerOptions, "controllerPatterns">): Promise<MockServer>;
2087
+ getMockServer(options?: Pick<ServerOptions, "controllerPatterns">): MockServer;
2088
+ ensureBootstrapped(options?: Pick<ServerOptions, "controllerPatterns">): Promise<void>;
2089
+ private createInjectFunction;
2047
2090
  private importControllers;
2048
2091
  private applyPlugins;
2049
2092
  /**
@@ -2069,34 +2112,6 @@ declare class Server<H extends NodeHttpClient = NodeHttpClient> implements Serve
2069
2112
  private setupAbortSignalHandler;
2070
2113
  }
2071
2114
 
2072
- declare class MockResponse<T = any> {
2073
- readonly response: Response$1;
2074
- constructor(response: Response$1);
2075
- body(): T;
2076
- statusCode(): number;
2077
- headers(): Record<string, string>;
2078
- cookies(): Record<string, string>;
2079
- assertStatus(status: number): this;
2080
- assertHeader(header: string, value: string): this;
2081
- assertHeaderExists(header: string): this;
2082
- assertHeaderNotExists(header: string): this;
2083
- assertCookie(name: string, value: string): this;
2084
- assertCookieExists(name: string): this;
2085
- assertCookieNotExists(name: string): this;
2086
- assertBodySubset(subset: Partial<T>): this;
2087
- assertBodyDeepEqual(expected: T): this;
2088
- assertBodyNotSubset(subset: Partial<T>): this;
2089
- assertBodyNotDeepEqual(expected: T): this;
2090
- assertCustom(assertion: (response: Response$1) => void): this;
2091
- private assertSubset;
2092
- private assertDeepEqual;
2093
- private assertNotSubset;
2094
- private assertNotDeepEqual;
2095
- private assertArraySubset;
2096
- private assertArrayDeepEqual;
2097
- private isObject;
2098
- }
2099
-
2100
2115
  /**
2101
2116
  * Type-safe options for the mock server
2102
2117
  * @template TBody - The request body type
@@ -2140,7 +2155,8 @@ declare class MockServer {
2140
2155
  readonly server: Server<NodeHttpClient>;
2141
2156
  private readonly logger;
2142
2157
  private ensureGraphQLHandler;
2143
- constructor(server: Server<NodeHttpClient>);
2158
+ private readonly bootstrapOptions?;
2159
+ constructor(server: Server<NodeHttpClient>, options?: Pick<ServerOptions, "controllerPatterns">);
2144
2160
  /**
2145
2161
  * Simulates an HTTP request without making an actual network call, useful for testing purposes
2146
2162
  * Executes the middleware chain and handler of the route
@@ -2300,6 +2316,8 @@ type CorsOptions = {
2300
2316
  methods?: CorsMethods[] | string;
2301
2317
  /**
2302
2318
  * Configures the Access-Control-Allow-Headers CORS header. Defaults to allowing all requested headers.
2319
+ * When omitted, Balda echoes `Access-Control-Request-Headers` on preflight requests.
2320
+ * Set this explicitly to override that default behavior.
2303
2321
  */
2304
2322
  allowedHeaders?: string[] | string;
2305
2323
  /**
@@ -2702,6 +2720,49 @@ type ResolvedServerOptions = {
2702
2720
  abortSignal?: AbortSignal;
2703
2721
  };
2704
2722
  type ServerErrorHandler = (req: Request, res: Response$1, next: NextFunction, error: Error) => SyncOrAsync;
2723
+ /**
2724
+ * A callable function with HTTP method shortcuts for injecting requests directly into the server.
2725
+ * Similar to Fastify's `inject`, it allows testing routes without network overhead.
2726
+ */
2727
+ interface InjectFunction {
2728
+ /**
2729
+ * Simulates an HTTP request without making an actual network call
2730
+ * @param method - The HTTP method (GET, POST, PUT, DELETE, PATCH)
2731
+ * @param path - The request path
2732
+ * @param options - Request options including body, headers, query params, etc.
2733
+ */
2734
+ <TResponse = any, TBody = any, TQuery extends Record<string, string> = any>(method: HttpMethod, path: string, options?: MockServerOptions<TBody, TQuery>): Promise<MockResponse<TResponse>>;
2735
+ /**
2736
+ * Type-safe GET request
2737
+ * @example
2738
+ * const res = await server.inject.get<UserResponse>("/users");
2739
+ */
2740
+ get<TResponse = any, TQuery extends Record<string, string> = any>(path: string, options?: Omit<MockServerOptions<never, TQuery>, "body" | "formData" | "urlencoded">): Promise<MockResponse<TResponse>>;
2741
+ /**
2742
+ * Type-safe POST request
2743
+ * @example
2744
+ * const res = await server.inject.post<UserResponse, CreateUserInput>("/users", { body: { name: "John" } });
2745
+ */
2746
+ post<TResponse = any, TBody = any, TQuery extends Record<string, string> = any>(path: string, options?: MockServerOptions<TBody, TQuery>): Promise<MockResponse<TResponse>>;
2747
+ /**
2748
+ * Type-safe PUT request
2749
+ * @example
2750
+ * const res = await server.inject.put<UserResponse>("/users/1", { body: { name: "Jane" } });
2751
+ */
2752
+ put<TResponse = any, TBody = any, TQuery extends Record<string, string> = any>(path: string, options?: MockServerOptions<TBody, TQuery>): Promise<MockResponse<TResponse>>;
2753
+ /**
2754
+ * Type-safe PATCH request
2755
+ * @example
2756
+ * const res = await server.inject.patch<UserResponse>("/users/1", { body: { name: "Jane" } });
2757
+ */
2758
+ patch<TResponse = any, TBody = any, TQuery extends Record<string, string> = any>(path: string, options?: MockServerOptions<TBody, TQuery>): Promise<MockResponse<TResponse>>;
2759
+ /**
2760
+ * Type-safe DELETE request
2761
+ * @example
2762
+ * const res = await server.inject.delete<DeleteResponse>("/users/1");
2763
+ */
2764
+ delete<TResponse = any, TQuery extends Record<string, string> = any>(path: string, options?: Omit<MockServerOptions<never, TQuery>, "body" | "formData">): Promise<MockResponse<TResponse>>;
2765
+ }
2705
2766
  interface ServerInterface {
2706
2767
  /**
2707
2768
  * Identifier for the balda server instance
@@ -2975,12 +3036,35 @@ interface ServerInterface {
2975
3036
  */
2976
3037
  disconnect: () => Promise<void>;
2977
3038
  /**
2978
- * Returns a mock server instance that can be used to test the server without starting it
2979
- * It will import the controllers and apply the plugins to the mock server
3039
+ * Returns a mock server instance that can be used to test the server without starting it.
3040
+ * The mock server lazily bootstraps (imports controllers, applies plugins) on the first request.
2980
3041
  * @param options - The options for the mock server
2981
3042
  * @param options.controllerPatterns - Custom controller patterns to import if the mock server must not be initialized with the same controller patterns as the server
2982
3043
  */
2983
- getMockServer: () => Promise<MockServer>;
3044
+ getMockServer: (options?: Pick<ServerOptions, "controllerPatterns">) => MockServer;
3045
+ /**
3046
+ * Inject requests directly into the server without network overhead.
3047
+ * Lazily bootstraps the server on the first call.
3048
+ * Supports both generic `inject(method, path, options)` and typed shortcuts like `inject.get()`, `inject.post()`, etc.
3049
+ *
3050
+ * @example
3051
+ * ```typescript
3052
+ * // Generic inject
3053
+ * const res = await server.inject("GET", "/users");
3054
+ *
3055
+ * // Typed shortcuts
3056
+ * const res = await server.inject.get<User[]>("/users");
3057
+ * const res = await server.inject.post<User, CreateUserInput>("/users", { body: { name: "John" } });
3058
+ * ```
3059
+ */
3060
+ inject: InjectFunction;
3061
+ /**
3062
+ * Ensures the server is bootstrapped (controllers imported, plugins applied).
3063
+ * This is called lazily by `inject()` and `MockServer.request()`, but can be called explicitly to pre-bootstrap.
3064
+ * This method is idempotent — subsequent calls after the first have no effect.
3065
+ * @param options - Optional controller patterns to import
3066
+ */
3067
+ ensureBootstrapped: (options?: Pick<ServerOptions, "controllerPatterns">) => Promise<void>;
2984
3068
  /**
2985
3069
  * Exit current runtime process with the given code based on the current runtime
2986
3070
  * @param code - The code to exit with, defaults to 0
@@ -4615,7 +4699,9 @@ declare const cookie: (options?: CookieMiddlewareOptions) => TypedMiddleware<{
4615
4699
  * ⚠️ SECURITY WARNING: By default, this plugin allows ALL origins ('*').
4616
4700
  * For production environments, explicitly configure allowed origins.
4617
4701
  *
4618
- * @param options CORS options (all optional)
4702
+ * @param options CORS options (all optional). Omitted options keep Balda's defaults,
4703
+ * including default methods and echoing `Access-Control-Request-Headers` on preflight
4704
+ * requests unless `allowedHeaders` is explicitly overridden.
4619
4705
  *
4620
4706
  * @example
4621
4707
  * // Development (permissive)
@@ -4752,7 +4838,7 @@ declare const trustProxy: (options?: TrustProxyOptions) => ServerRouteMiddleware
4752
4838
  * @param options.urlencoded - The options for the URL-encoded middleware.
4753
4839
  * @param options.fileParser - The options for the file parser middleware.
4754
4840
  */
4755
- declare const bodyParser: (options: BodyParserOptions) => ServerRouteMiddleware;
4841
+ declare const bodyParser: (options?: BodyParserOptions) => ServerRouteMiddleware;
4756
4842
 
4757
4843
  declare const createPolicyDecorator: <T extends Record<string, PolicyProvider>>(manager: PolicyManager<T>) => PolicyDecorator<T>;
4758
4844
 
@@ -4943,4 +5029,4 @@ declare enum CacheStatus {
4943
5029
  */
4944
5030
  declare const router: ClientRouter;
4945
5031
 
4946
- export { type AsyncLocalStorageContextSetters, AzureBlobStorageProvider, BaseCron, BasePlugin, type BaseStorageProviderOptions, type BlobStorageProviderOptions, type BodyParserOptions, type BodylessMethodOptions, BullMQConfiguration, type BullMQConfigurationOptions, BullMQPubSub, CACHE_STATUS_HEADER, type CacheKeyIncludes, type CacheMiddlewareOptions, type CachePluginOptions, type CacheProvider, type CacheRedisOptions, type CacheRouteConfig, CacheService, type CacheServiceInterface, type CacheStats, CacheStatus, Command, type CommandOptions, CommandRegistry, type CompressionOptions, type CookieMiddlewareOptions, type CorsOptions, type CronSchedule, type CronScheduleParams, CronService, type CronUIOptions, CustomAdapter, type CustomQueueConfiguration, type CustomStorageProviderOptions, CustomTypedQueue, type CustomValidationError, DEFAULT_CACHE_OPTIONS, EdgeAdapter, EjsAdapter, type ExtractParams, GraphQL, type GraphQLContext, type GraphQLOptions, type GraphQLResolverFunction, type GraphQLResolverMap, type GraphQLResolverType, type GraphQLResolvers, type GraphQLSchemaInput, type GraphQLTypeDef, type GroupRouter, HandlebarsAdapter, type HelmetOptions, type HttpMethod, type HttpsOptions, type InferMiddlewareExtension, type InferMiddlewareExtensions, type InferResponseMap, type InferSchemaType, LocalStorageProvider, type LocalStorageProviderOptions, type LockBehavior, type LogOptions, type LoggerOptions, type MailOptions, MailOptionsBuilder, MailProvider, type MailProviderInterface, Mailer, type MailerInterface, type MailerOptions, type MailerProviderOptions, MemoryCacheProvider, MemoryPubSub, type MethodOverrideOptions, MockResponse, MockServer, type MockServerOptions, type MqttConnectionOptions, type MqttHandler, type MqttPublishOptions, MqttService, type MqttSubscribeOptions, type MqttSubscription, type MqttTopics, MustacheAdapter, type NextFunction, type NodeHttpClient, type NodeServer as NodeHttpServerClient, PGBossConfiguration, type PGBossConfigurationOptions, PGBossPubSub, type PolicyDecorator, type PolicyErrorHandlerOptions, PolicyManager, type PolicyProvider, type PolicyRouteConfig, type PublishTopic, QueueManager, QueueService, type RateLimiterKeyOptions, RedisCacheProvider, Request, type RequestSchema, Response$1 as Response, type ResponseBodyForStatus, type RuntimeServer, S3StorageProvider, type S3StorageProviderOptions, SQSConfiguration, type SQSConfigurationOptions, SQSPubSub, type CacheMetrics as SchemaCacheMetrics, type SerializeOptions, type SerializedValidationError, Server, type ServerConnectInput, type ServerErrorHandler, type ServerHook, type ServerInterface, type ServerListenCallback, type ServerOptions, type ServerPlugin, type ServerPluginConfig, type ServerRouteHandler, type ServerRouteMiddleware, type ServerTapOptions, type SessionOptions, type SignalEvent, type StandardMethodOptions, type StaticPluginOptions, Storage, type StorageInterface, type StorageOptions, type StorageProviderOptions, type TemplateMailOptions, type TimeoutOptions, type TrustProxyOptions, type TypedCacheKeyIncludes, type TypedCacheRouteConfig, type TypedHandler, type TypedMiddleware, TypedQueue, type TypedRouteMetadata, type ValidatedData, type ValidationErrorHandlerOptions, type ValidationOptions, arg, asyncLocalStorage, asyncStorage, bodyParser, bullmqQueue, cache, cacheMiddleware, clearAllCaches as clearAllSchemaCaches, commandRegistry, compression, controller, cookie, cors, createExpressAdapter, createPolicyDecorator, createQueue, cron, cronUIInstance, cronUi, Server as default, defineMiddleware, defineQueueConfiguration, del, expressHandler, expressMiddleware, flag, get, getCacheService, getCacheMetrics as getSchemaCacheMetrics, hash, helmet, initCacheService, log, logCacheMetrics as logSchemaCacheMetrics, logger, memoryQueue, methodOverride, middleware, mountExpressRouter, mqtt, patch, pgbossQueue, post, put, rateLimiter, resetCacheService, router, serialize, serveStatic, session, setCronGlobalErrorHandler, setMqttGlobalErrorHandler, sqsQueue, timeout as timeoutMw, trustProxy, validate };
5032
+ export { type AsyncLocalStorageContextSetters, AzureBlobStorageProvider, BaseCron, BasePlugin, type BaseStorageProviderOptions, type BlobStorageProviderOptions, type BodyParserOptions, type BodylessMethodOptions, BullMQConfiguration, type BullMQConfigurationOptions, BullMQPubSub, CACHE_STATUS_HEADER, type CacheKeyIncludes, type CacheMiddlewareOptions, type CachePluginOptions, type CacheProvider, type CacheRedisOptions, type CacheRouteConfig, CacheService, type CacheServiceInterface, type CacheStats, CacheStatus, Command, type CommandOptions, CommandRegistry, type CompressionOptions, type CookieMiddlewareOptions, type CorsOptions, type CronSchedule, type CronScheduleParams, CronService, type CronUIOptions, CustomAdapter, type CustomQueueConfiguration, type CustomStorageProviderOptions, CustomTypedQueue, type CustomValidationError, DEFAULT_CACHE_OPTIONS, EdgeAdapter, EjsAdapter, type ExtractParams, GraphQL, type GraphQLContext, type GraphQLOptions, type GraphQLResolverFunction, type GraphQLResolverMap, type GraphQLResolverType, type GraphQLResolvers, type GraphQLSchemaInput, type GraphQLTypeDef, type GroupRouter, HandlebarsAdapter, type HelmetOptions, type HttpMethod, type HttpsOptions, type InferMiddlewareExtension, type InferMiddlewareExtensions, type InferResponseMap, type InferSchemaType, type InjectFunction, LocalStorageProvider, type LocalStorageProviderOptions, type LockBehavior, type LogOptions, type LoggerOptions, type MailOptions, MailOptionsBuilder, MailProvider, type MailProviderInterface, Mailer, type MailerInterface, type MailerOptions, type MailerProviderOptions, MemoryCacheProvider, MemoryPubSub, type MethodOverrideOptions, MockResponse, MockServer, type MockServerOptions, type MqttConnectionOptions, type MqttHandler, type MqttPublishOptions, MqttService, type MqttSubscribeOptions, type MqttSubscription, type MqttTopics, MustacheAdapter, type NextFunction, type NodeHttpClient, type NodeServer as NodeHttpServerClient, PGBossConfiguration, type PGBossConfigurationOptions, PGBossPubSub, type PolicyDecorator, type PolicyErrorHandlerOptions, PolicyManager, type PolicyProvider, type PolicyRouteConfig, type PublishTopic, QueueManager, QueueService, type RateLimiterKeyOptions, RedisCacheProvider, Request, type RequestSchema, Response$1 as Response, type ResponseBodyForStatus, type RuntimeServer, S3StorageProvider, type S3StorageProviderOptions, SQSConfiguration, type SQSConfigurationOptions, SQSPubSub, type CacheMetrics as SchemaCacheMetrics, type SerializeOptions, type SerializedValidationError, Server, type ServerConnectInput, type ServerErrorHandler, type ServerHook, type ServerInterface, type ServerListenCallback, type ServerOptions, type ServerPlugin, type ServerPluginConfig, type ServerRouteHandler, type ServerRouteMiddleware, type ServerTapOptions, type SessionOptions, type SignalEvent, type StandardMethodOptions, type StaticPluginOptions, Storage, type StorageInterface, type StorageOptions, type StorageProviderOptions, type TemplateMailOptions, type TimeoutOptions, type TrustProxyOptions, type TypedCacheKeyIncludes, type TypedCacheRouteConfig, type TypedHandler, type TypedMiddleware, TypedQueue, type TypedRouteMetadata, type ValidatedData, type ValidationErrorHandlerOptions, type ValidationOptions, arg, asyncLocalStorage, asyncStorage, bodyParser, bullmqQueue, cache, cacheMiddleware, clearAllCaches as clearAllSchemaCaches, commandRegistry, compression, controller, cookie, cors, createExpressAdapter, createPolicyDecorator, createQueue, cron, cronUIInstance, cronUi, Server as default, defineMiddleware, defineQueueConfiguration, del, expressHandler, expressMiddleware, flag, get, getCacheService, getCacheMetrics as getSchemaCacheMetrics, hash, helmet, initCacheService, log, logCacheMetrics as logSchemaCacheMetrics, logger, memoryQueue, methodOverride, middleware, mountExpressRouter, mqtt, patch, pgbossQueue, post, put, rateLimiter, resetCacheService, router, serialize, serveStatic, session, setCronGlobalErrorHandler, setMqttGlobalErrorHandler, sqsQueue, timeout as timeoutMw, trustProxy, validate };
package/lib/index.d.ts CHANGED
@@ -349,6 +349,12 @@ declare class Request<Params extends Record<string, string> = Record<string, str
349
349
  file(fieldName: string): FormFile | null;
350
350
  get cookies(): Record<string, string>;
351
351
  set cookies(value: Record<string, string>);
352
+ /**
353
+ * Returns cookies when the cookie middleware has populated them, otherwise undefined.
354
+ * Useful for compatibility layers that should not throw when cookies are unavailable.
355
+ * @internal
356
+ */
357
+ getOptionalCookies(): Record<string, string> | undefined;
352
358
  /**
353
359
  * The cookie of the request.
354
360
  * @cookie middleware is required
@@ -362,6 +368,12 @@ declare class Request<Params extends Record<string, string> = Record<string, str
362
368
  timeout?: boolean;
363
369
  get session(): Record<string, any> | undefined;
364
370
  set session(value: Record<string, any> | undefined);
371
+ /**
372
+ * Returns session data when the session middleware has populated it, otherwise undefined.
373
+ * Useful for compatibility layers that should not throw when sessions are unavailable.
374
+ * @internal
375
+ */
376
+ getOptionalSession(): Record<string, any> | undefined;
365
377
  /**
366
378
  * Shared throwing functions to avoid per-instance closure allocation.
367
379
  * @internal
@@ -1638,6 +1650,34 @@ declare class GraphQL {
1638
1650
  private ensureTypeDefsArray;
1639
1651
  }
1640
1652
 
1653
+ declare class MockResponse<T = any> {
1654
+ readonly response: Response$1;
1655
+ constructor(response: Response$1);
1656
+ body(): T;
1657
+ statusCode(): number;
1658
+ headers(): Record<string, string>;
1659
+ cookies(): Record<string, string>;
1660
+ assertStatus(status: number): this;
1661
+ assertHeader(header: string, value: string): this;
1662
+ assertHeaderExists(header: string): this;
1663
+ assertHeaderNotExists(header: string): this;
1664
+ assertCookie(name: string, value: string): this;
1665
+ assertCookieExists(name: string): this;
1666
+ assertCookieNotExists(name: string): this;
1667
+ assertBodySubset(subset: Partial<T>): this;
1668
+ assertBodyDeepEqual(expected: T): this;
1669
+ assertBodyNotSubset(subset: Partial<T>): this;
1670
+ assertBodyNotDeepEqual(expected: T): this;
1671
+ assertCustom(assertion: (response: Response$1) => void): this;
1672
+ private assertSubset;
1673
+ private assertDeepEqual;
1674
+ private assertNotSubset;
1675
+ private assertNotDeepEqual;
1676
+ private assertArraySubset;
1677
+ private assertArrayDeepEqual;
1678
+ private isObject;
1679
+ }
1680
+
1641
1681
  declare class NativeFs {
1642
1682
  glob(...args: Parameters<typeof glob>): Promise<string[]>;
1643
1683
  mkdir(path: string, options?: {
@@ -1976,6 +2016,7 @@ declare class Server<H extends NodeHttpClient = NodeHttpClient> implements Serve
1976
2016
  isListening: boolean;
1977
2017
  isProduction: boolean;
1978
2018
  graphql: GraphQL;
2019
+ readonly inject: InjectFunction;
1979
2020
  /**
1980
2021
  * The constructor for the server
1981
2022
  * @warning Routes will only be defined after calling the `listen` method so you're free to define middlewares before calling it
@@ -2043,7 +2084,9 @@ declare class Server<H extends NodeHttpClient = NodeHttpClient> implements Serve
2043
2084
  * @returns A promise that resolves when the server is disconnected
2044
2085
  */
2045
2086
  disconnect(): Promise<void>;
2046
- getMockServer(options?: Pick<ServerOptions, "controllerPatterns">): Promise<MockServer>;
2087
+ getMockServer(options?: Pick<ServerOptions, "controllerPatterns">): MockServer;
2088
+ ensureBootstrapped(options?: Pick<ServerOptions, "controllerPatterns">): Promise<void>;
2089
+ private createInjectFunction;
2047
2090
  private importControllers;
2048
2091
  private applyPlugins;
2049
2092
  /**
@@ -2069,34 +2112,6 @@ declare class Server<H extends NodeHttpClient = NodeHttpClient> implements Serve
2069
2112
  private setupAbortSignalHandler;
2070
2113
  }
2071
2114
 
2072
- declare class MockResponse<T = any> {
2073
- readonly response: Response$1;
2074
- constructor(response: Response$1);
2075
- body(): T;
2076
- statusCode(): number;
2077
- headers(): Record<string, string>;
2078
- cookies(): Record<string, string>;
2079
- assertStatus(status: number): this;
2080
- assertHeader(header: string, value: string): this;
2081
- assertHeaderExists(header: string): this;
2082
- assertHeaderNotExists(header: string): this;
2083
- assertCookie(name: string, value: string): this;
2084
- assertCookieExists(name: string): this;
2085
- assertCookieNotExists(name: string): this;
2086
- assertBodySubset(subset: Partial<T>): this;
2087
- assertBodyDeepEqual(expected: T): this;
2088
- assertBodyNotSubset(subset: Partial<T>): this;
2089
- assertBodyNotDeepEqual(expected: T): this;
2090
- assertCustom(assertion: (response: Response$1) => void): this;
2091
- private assertSubset;
2092
- private assertDeepEqual;
2093
- private assertNotSubset;
2094
- private assertNotDeepEqual;
2095
- private assertArraySubset;
2096
- private assertArrayDeepEqual;
2097
- private isObject;
2098
- }
2099
-
2100
2115
  /**
2101
2116
  * Type-safe options for the mock server
2102
2117
  * @template TBody - The request body type
@@ -2140,7 +2155,8 @@ declare class MockServer {
2140
2155
  readonly server: Server<NodeHttpClient>;
2141
2156
  private readonly logger;
2142
2157
  private ensureGraphQLHandler;
2143
- constructor(server: Server<NodeHttpClient>);
2158
+ private readonly bootstrapOptions?;
2159
+ constructor(server: Server<NodeHttpClient>, options?: Pick<ServerOptions, "controllerPatterns">);
2144
2160
  /**
2145
2161
  * Simulates an HTTP request without making an actual network call, useful for testing purposes
2146
2162
  * Executes the middleware chain and handler of the route
@@ -2300,6 +2316,8 @@ type CorsOptions = {
2300
2316
  methods?: CorsMethods[] | string;
2301
2317
  /**
2302
2318
  * Configures the Access-Control-Allow-Headers CORS header. Defaults to allowing all requested headers.
2319
+ * When omitted, Balda echoes `Access-Control-Request-Headers` on preflight requests.
2320
+ * Set this explicitly to override that default behavior.
2303
2321
  */
2304
2322
  allowedHeaders?: string[] | string;
2305
2323
  /**
@@ -2702,6 +2720,49 @@ type ResolvedServerOptions = {
2702
2720
  abortSignal?: AbortSignal;
2703
2721
  };
2704
2722
  type ServerErrorHandler = (req: Request, res: Response$1, next: NextFunction, error: Error) => SyncOrAsync;
2723
+ /**
2724
+ * A callable function with HTTP method shortcuts for injecting requests directly into the server.
2725
+ * Similar to Fastify's `inject`, it allows testing routes without network overhead.
2726
+ */
2727
+ interface InjectFunction {
2728
+ /**
2729
+ * Simulates an HTTP request without making an actual network call
2730
+ * @param method - The HTTP method (GET, POST, PUT, DELETE, PATCH)
2731
+ * @param path - The request path
2732
+ * @param options - Request options including body, headers, query params, etc.
2733
+ */
2734
+ <TResponse = any, TBody = any, TQuery extends Record<string, string> = any>(method: HttpMethod, path: string, options?: MockServerOptions<TBody, TQuery>): Promise<MockResponse<TResponse>>;
2735
+ /**
2736
+ * Type-safe GET request
2737
+ * @example
2738
+ * const res = await server.inject.get<UserResponse>("/users");
2739
+ */
2740
+ get<TResponse = any, TQuery extends Record<string, string> = any>(path: string, options?: Omit<MockServerOptions<never, TQuery>, "body" | "formData" | "urlencoded">): Promise<MockResponse<TResponse>>;
2741
+ /**
2742
+ * Type-safe POST request
2743
+ * @example
2744
+ * const res = await server.inject.post<UserResponse, CreateUserInput>("/users", { body: { name: "John" } });
2745
+ */
2746
+ post<TResponse = any, TBody = any, TQuery extends Record<string, string> = any>(path: string, options?: MockServerOptions<TBody, TQuery>): Promise<MockResponse<TResponse>>;
2747
+ /**
2748
+ * Type-safe PUT request
2749
+ * @example
2750
+ * const res = await server.inject.put<UserResponse>("/users/1", { body: { name: "Jane" } });
2751
+ */
2752
+ put<TResponse = any, TBody = any, TQuery extends Record<string, string> = any>(path: string, options?: MockServerOptions<TBody, TQuery>): Promise<MockResponse<TResponse>>;
2753
+ /**
2754
+ * Type-safe PATCH request
2755
+ * @example
2756
+ * const res = await server.inject.patch<UserResponse>("/users/1", { body: { name: "Jane" } });
2757
+ */
2758
+ patch<TResponse = any, TBody = any, TQuery extends Record<string, string> = any>(path: string, options?: MockServerOptions<TBody, TQuery>): Promise<MockResponse<TResponse>>;
2759
+ /**
2760
+ * Type-safe DELETE request
2761
+ * @example
2762
+ * const res = await server.inject.delete<DeleteResponse>("/users/1");
2763
+ */
2764
+ delete<TResponse = any, TQuery extends Record<string, string> = any>(path: string, options?: Omit<MockServerOptions<never, TQuery>, "body" | "formData">): Promise<MockResponse<TResponse>>;
2765
+ }
2705
2766
  interface ServerInterface {
2706
2767
  /**
2707
2768
  * Identifier for the balda server instance
@@ -2975,12 +3036,35 @@ interface ServerInterface {
2975
3036
  */
2976
3037
  disconnect: () => Promise<void>;
2977
3038
  /**
2978
- * Returns a mock server instance that can be used to test the server without starting it
2979
- * It will import the controllers and apply the plugins to the mock server
3039
+ * Returns a mock server instance that can be used to test the server without starting it.
3040
+ * The mock server lazily bootstraps (imports controllers, applies plugins) on the first request.
2980
3041
  * @param options - The options for the mock server
2981
3042
  * @param options.controllerPatterns - Custom controller patterns to import if the mock server must not be initialized with the same controller patterns as the server
2982
3043
  */
2983
- getMockServer: () => Promise<MockServer>;
3044
+ getMockServer: (options?: Pick<ServerOptions, "controllerPatterns">) => MockServer;
3045
+ /**
3046
+ * Inject requests directly into the server without network overhead.
3047
+ * Lazily bootstraps the server on the first call.
3048
+ * Supports both generic `inject(method, path, options)` and typed shortcuts like `inject.get()`, `inject.post()`, etc.
3049
+ *
3050
+ * @example
3051
+ * ```typescript
3052
+ * // Generic inject
3053
+ * const res = await server.inject("GET", "/users");
3054
+ *
3055
+ * // Typed shortcuts
3056
+ * const res = await server.inject.get<User[]>("/users");
3057
+ * const res = await server.inject.post<User, CreateUserInput>("/users", { body: { name: "John" } });
3058
+ * ```
3059
+ */
3060
+ inject: InjectFunction;
3061
+ /**
3062
+ * Ensures the server is bootstrapped (controllers imported, plugins applied).
3063
+ * This is called lazily by `inject()` and `MockServer.request()`, but can be called explicitly to pre-bootstrap.
3064
+ * This method is idempotent — subsequent calls after the first have no effect.
3065
+ * @param options - Optional controller patterns to import
3066
+ */
3067
+ ensureBootstrapped: (options?: Pick<ServerOptions, "controllerPatterns">) => Promise<void>;
2984
3068
  /**
2985
3069
  * Exit current runtime process with the given code based on the current runtime
2986
3070
  * @param code - The code to exit with, defaults to 0
@@ -4615,7 +4699,9 @@ declare const cookie: (options?: CookieMiddlewareOptions) => TypedMiddleware<{
4615
4699
  * ⚠️ SECURITY WARNING: By default, this plugin allows ALL origins ('*').
4616
4700
  * For production environments, explicitly configure allowed origins.
4617
4701
  *
4618
- * @param options CORS options (all optional)
4702
+ * @param options CORS options (all optional). Omitted options keep Balda's defaults,
4703
+ * including default methods and echoing `Access-Control-Request-Headers` on preflight
4704
+ * requests unless `allowedHeaders` is explicitly overridden.
4619
4705
  *
4620
4706
  * @example
4621
4707
  * // Development (permissive)
@@ -4752,7 +4838,7 @@ declare const trustProxy: (options?: TrustProxyOptions) => ServerRouteMiddleware
4752
4838
  * @param options.urlencoded - The options for the URL-encoded middleware.
4753
4839
  * @param options.fileParser - The options for the file parser middleware.
4754
4840
  */
4755
- declare const bodyParser: (options: BodyParserOptions) => ServerRouteMiddleware;
4841
+ declare const bodyParser: (options?: BodyParserOptions) => ServerRouteMiddleware;
4756
4842
 
4757
4843
  declare const createPolicyDecorator: <T extends Record<string, PolicyProvider>>(manager: PolicyManager<T>) => PolicyDecorator<T>;
4758
4844
 
@@ -4943,4 +5029,4 @@ declare enum CacheStatus {
4943
5029
  */
4944
5030
  declare const router: ClientRouter;
4945
5031
 
4946
- export { type AsyncLocalStorageContextSetters, AzureBlobStorageProvider, BaseCron, BasePlugin, type BaseStorageProviderOptions, type BlobStorageProviderOptions, type BodyParserOptions, type BodylessMethodOptions, BullMQConfiguration, type BullMQConfigurationOptions, BullMQPubSub, CACHE_STATUS_HEADER, type CacheKeyIncludes, type CacheMiddlewareOptions, type CachePluginOptions, type CacheProvider, type CacheRedisOptions, type CacheRouteConfig, CacheService, type CacheServiceInterface, type CacheStats, CacheStatus, Command, type CommandOptions, CommandRegistry, type CompressionOptions, type CookieMiddlewareOptions, type CorsOptions, type CronSchedule, type CronScheduleParams, CronService, type CronUIOptions, CustomAdapter, type CustomQueueConfiguration, type CustomStorageProviderOptions, CustomTypedQueue, type CustomValidationError, DEFAULT_CACHE_OPTIONS, EdgeAdapter, EjsAdapter, type ExtractParams, GraphQL, type GraphQLContext, type GraphQLOptions, type GraphQLResolverFunction, type GraphQLResolverMap, type GraphQLResolverType, type GraphQLResolvers, type GraphQLSchemaInput, type GraphQLTypeDef, type GroupRouter, HandlebarsAdapter, type HelmetOptions, type HttpMethod, type HttpsOptions, type InferMiddlewareExtension, type InferMiddlewareExtensions, type InferResponseMap, type InferSchemaType, LocalStorageProvider, type LocalStorageProviderOptions, type LockBehavior, type LogOptions, type LoggerOptions, type MailOptions, MailOptionsBuilder, MailProvider, type MailProviderInterface, Mailer, type MailerInterface, type MailerOptions, type MailerProviderOptions, MemoryCacheProvider, MemoryPubSub, type MethodOverrideOptions, MockResponse, MockServer, type MockServerOptions, type MqttConnectionOptions, type MqttHandler, type MqttPublishOptions, MqttService, type MqttSubscribeOptions, type MqttSubscription, type MqttTopics, MustacheAdapter, type NextFunction, type NodeHttpClient, type NodeServer as NodeHttpServerClient, PGBossConfiguration, type PGBossConfigurationOptions, PGBossPubSub, type PolicyDecorator, type PolicyErrorHandlerOptions, PolicyManager, type PolicyProvider, type PolicyRouteConfig, type PublishTopic, QueueManager, QueueService, type RateLimiterKeyOptions, RedisCacheProvider, Request, type RequestSchema, Response$1 as Response, type ResponseBodyForStatus, type RuntimeServer, S3StorageProvider, type S3StorageProviderOptions, SQSConfiguration, type SQSConfigurationOptions, SQSPubSub, type CacheMetrics as SchemaCacheMetrics, type SerializeOptions, type SerializedValidationError, Server, type ServerConnectInput, type ServerErrorHandler, type ServerHook, type ServerInterface, type ServerListenCallback, type ServerOptions, type ServerPlugin, type ServerPluginConfig, type ServerRouteHandler, type ServerRouteMiddleware, type ServerTapOptions, type SessionOptions, type SignalEvent, type StandardMethodOptions, type StaticPluginOptions, Storage, type StorageInterface, type StorageOptions, type StorageProviderOptions, type TemplateMailOptions, type TimeoutOptions, type TrustProxyOptions, type TypedCacheKeyIncludes, type TypedCacheRouteConfig, type TypedHandler, type TypedMiddleware, TypedQueue, type TypedRouteMetadata, type ValidatedData, type ValidationErrorHandlerOptions, type ValidationOptions, arg, asyncLocalStorage, asyncStorage, bodyParser, bullmqQueue, cache, cacheMiddleware, clearAllCaches as clearAllSchemaCaches, commandRegistry, compression, controller, cookie, cors, createExpressAdapter, createPolicyDecorator, createQueue, cron, cronUIInstance, cronUi, Server as default, defineMiddleware, defineQueueConfiguration, del, expressHandler, expressMiddleware, flag, get, getCacheService, getCacheMetrics as getSchemaCacheMetrics, hash, helmet, initCacheService, log, logCacheMetrics as logSchemaCacheMetrics, logger, memoryQueue, methodOverride, middleware, mountExpressRouter, mqtt, patch, pgbossQueue, post, put, rateLimiter, resetCacheService, router, serialize, serveStatic, session, setCronGlobalErrorHandler, setMqttGlobalErrorHandler, sqsQueue, timeout as timeoutMw, trustProxy, validate };
5032
+ export { type AsyncLocalStorageContextSetters, AzureBlobStorageProvider, BaseCron, BasePlugin, type BaseStorageProviderOptions, type BlobStorageProviderOptions, type BodyParserOptions, type BodylessMethodOptions, BullMQConfiguration, type BullMQConfigurationOptions, BullMQPubSub, CACHE_STATUS_HEADER, type CacheKeyIncludes, type CacheMiddlewareOptions, type CachePluginOptions, type CacheProvider, type CacheRedisOptions, type CacheRouteConfig, CacheService, type CacheServiceInterface, type CacheStats, CacheStatus, Command, type CommandOptions, CommandRegistry, type CompressionOptions, type CookieMiddlewareOptions, type CorsOptions, type CronSchedule, type CronScheduleParams, CronService, type CronUIOptions, CustomAdapter, type CustomQueueConfiguration, type CustomStorageProviderOptions, CustomTypedQueue, type CustomValidationError, DEFAULT_CACHE_OPTIONS, EdgeAdapter, EjsAdapter, type ExtractParams, GraphQL, type GraphQLContext, type GraphQLOptions, type GraphQLResolverFunction, type GraphQLResolverMap, type GraphQLResolverType, type GraphQLResolvers, type GraphQLSchemaInput, type GraphQLTypeDef, type GroupRouter, HandlebarsAdapter, type HelmetOptions, type HttpMethod, type HttpsOptions, type InferMiddlewareExtension, type InferMiddlewareExtensions, type InferResponseMap, type InferSchemaType, type InjectFunction, LocalStorageProvider, type LocalStorageProviderOptions, type LockBehavior, type LogOptions, type LoggerOptions, type MailOptions, MailOptionsBuilder, MailProvider, type MailProviderInterface, Mailer, type MailerInterface, type MailerOptions, type MailerProviderOptions, MemoryCacheProvider, MemoryPubSub, type MethodOverrideOptions, MockResponse, MockServer, type MockServerOptions, type MqttConnectionOptions, type MqttHandler, type MqttPublishOptions, MqttService, type MqttSubscribeOptions, type MqttSubscription, type MqttTopics, MustacheAdapter, type NextFunction, type NodeHttpClient, type NodeServer as NodeHttpServerClient, PGBossConfiguration, type PGBossConfigurationOptions, PGBossPubSub, type PolicyDecorator, type PolicyErrorHandlerOptions, PolicyManager, type PolicyProvider, type PolicyRouteConfig, type PublishTopic, QueueManager, QueueService, type RateLimiterKeyOptions, RedisCacheProvider, Request, type RequestSchema, Response$1 as Response, type ResponseBodyForStatus, type RuntimeServer, S3StorageProvider, type S3StorageProviderOptions, SQSConfiguration, type SQSConfigurationOptions, SQSPubSub, type CacheMetrics as SchemaCacheMetrics, type SerializeOptions, type SerializedValidationError, Server, type ServerConnectInput, type ServerErrorHandler, type ServerHook, type ServerInterface, type ServerListenCallback, type ServerOptions, type ServerPlugin, type ServerPluginConfig, type ServerRouteHandler, type ServerRouteMiddleware, type ServerTapOptions, type SessionOptions, type SignalEvent, type StandardMethodOptions, type StaticPluginOptions, Storage, type StorageInterface, type StorageOptions, type StorageProviderOptions, type TemplateMailOptions, type TimeoutOptions, type TrustProxyOptions, type TypedCacheKeyIncludes, type TypedCacheRouteConfig, type TypedHandler, type TypedMiddleware, TypedQueue, type TypedRouteMetadata, type ValidatedData, type ValidationErrorHandlerOptions, type ValidationOptions, arg, asyncLocalStorage, asyncStorage, bodyParser, bullmqQueue, cache, cacheMiddleware, clearAllCaches as clearAllSchemaCaches, commandRegistry, compression, controller, cookie, cors, createExpressAdapter, createPolicyDecorator, createQueue, cron, cronUIInstance, cronUi, Server as default, defineMiddleware, defineQueueConfiguration, del, expressHandler, expressMiddleware, flag, get, getCacheService, getCacheMetrics as getSchemaCacheMetrics, hash, helmet, initCacheService, log, logCacheMetrics as logSchemaCacheMetrics, logger, memoryQueue, methodOverride, middleware, mountExpressRouter, mqtt, patch, pgbossQueue, post, put, rateLimiter, resetCacheService, router, serialize, serveStatic, session, setCronGlobalErrorHandler, setMqttGlobalErrorHandler, sqsQueue, timeout as timeoutMw, trustProxy, validate };