balda 0.0.1

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.ts ADDED
@@ -0,0 +1,3077 @@
1
+ import { schedule, TaskContext } from 'node-cron';
2
+ import { ZodType, ZodAny } from 'zod';
3
+ import { Ajv } from 'ajv';
4
+ import { ServerResponse, IncomingMessage, Server as Server$2 } from 'node:http';
5
+ import { Http2Server } from 'node:http2';
6
+ import { Server as Server$1, ServerOptions as ServerOptions$1 } from 'node:https';
7
+ export { ServerOptions as HttpsServerOptions } from 'node:https';
8
+ import { GraphQLSchema } from 'graphql';
9
+ import { createSchema, createYoga } from 'graphql-yoga';
10
+ import { RequestHandler, Router as Router$1, IRouter } from 'express';
11
+ export { ErrorRequestHandler as ExpressErrorMiddleware, RequestHandler as ExpressMiddleware, NextFunction as ExpressNextFunction, Request as ExpressRequest, Response as ExpressResponse } from 'express';
12
+ import * as pino from 'pino';
13
+ import pino__default, { pino as pino$1 } from 'pino';
14
+ import { Queue, Job } from 'bullmq';
15
+ import PgBoss from 'pg-boss';
16
+ import { SQSClient, SQSClientConfig } from '@aws-sdk/client-sqs';
17
+ import { IClientSubscribeOptions, IClientOptions, IClientPublishOptions, MqttClient } from 'mqtt';
18
+ import { AsyncLocalStorage } from 'node:async_hooks';
19
+ import { S3Client } from '@aws-sdk/client-s3';
20
+
21
+ type CronSchedule = {
22
+ name: string;
23
+ args: Parameters<typeof schedule>;
24
+ };
25
+ type CronScheduleParams = Parameters<typeof schedule>;
26
+
27
+ /**
28
+ * Decorator to schedule a cron job. Must be applied to a class method. By default, the cron job will not overlap with other cron jobs of the same type.
29
+ * ```ts
30
+ * @cron('* * * * *', { timezone: 'Europe/Istanbul' })
31
+ * async test() {
32
+ * console.log('test');
33
+ * }
34
+ * ```
35
+ */
36
+ declare const cron: (schedule: CronScheduleParams[0], options?: CronScheduleParams[2]) => (target: any, propertyKey: string, descriptor: PropertyDescriptor) => PropertyDescriptor;
37
+
38
+ type FlagType = "boolean" | "string" | "number" | "list";
39
+ type InferFlagType<T extends FlagType> = T extends "boolean" ? boolean : T extends "string" ? string : T extends "number" ? number : T extends "list" ? string[] : never;
40
+ type ArgOptions = {
41
+ /**
42
+ * The description of the argument.
43
+ */
44
+ description?: string;
45
+ /**
46
+ * Whether the argument is required.
47
+ * @default false
48
+ */
49
+ required?: boolean;
50
+ /**
51
+ * The default value of the argument.
52
+ */
53
+ defaultValue?: string;
54
+ /**
55
+ * A function to parse the argument value.
56
+ * @default The value is returned as is.
57
+ */
58
+ parse?: (value: string) => string;
59
+ };
60
+ type FlagOptions<T extends FlagType> = {
61
+ /**
62
+ * The description of the flag.
63
+ */
64
+ description?: string;
65
+ /**
66
+ * The type of the flag.
67
+ */
68
+ type: T;
69
+ /**
70
+ * The name of the flag.
71
+ * @default The name of the field.
72
+ */
73
+ name?: string;
74
+ /**
75
+ * The aliases of the flag.
76
+ */
77
+ aliases?: string[] | string;
78
+ /**
79
+ * The default value of the flag.
80
+ */
81
+ defaultValue?: InferFlagType<T>;
82
+ /**
83
+ * Whether the flag is required.
84
+ * @default false
85
+ */
86
+ required?: boolean;
87
+ /**
88
+ * A function to parse the flag value.
89
+ * @default The value is returned as is.
90
+ */
91
+ parse?: (value: any) => InferFlagType<T>;
92
+ };
93
+
94
+ declare const VALIDATION_ERROR_SYMBOL = "VALIDATION_ERROR";
95
+ declare const ARG_SYMBOL = "ARG";
96
+ /**
97
+ * Decorator to mark a field of a command class as an argument.
98
+ * @param options - The options for the argument.
99
+ * @warning Arguments are evaluated in the order they are defined in the Command class.
100
+ */
101
+ declare const arg: (options: ArgOptions) => (target: any, propertyKey: string) => void;
102
+
103
+ declare const flag: {
104
+ <T extends FlagType>(options: FlagOptions<T>): (target: any, propertyKey: string) => void;
105
+ boolean(options: Omit<FlagOptions<"boolean">, "type">): (target: any, propertyKey: string) => void;
106
+ string(options: Omit<FlagOptions<"string">, "type">): (target: any, propertyKey: string) => void;
107
+ number(options: Omit<FlagOptions<"number">, "type">): (target: any, propertyKey: string) => void;
108
+ list(options: Omit<FlagOptions<"list">, "type">): (target: any, propertyKey: string) => void;
109
+ };
110
+
111
+ /**
112
+ * Type of Swagger UI to use
113
+ */
114
+ type SwaggerUIType = "standard" | "rapidoc" | "scalar" | "elements" | "custom";
115
+ type HTMLString = string;
116
+ /**
117
+ * Custom UI generator function that takes the spec URL and global options and returns HTML
118
+ */
119
+ type CustomUIGenerator = (specUrl: string, globalOptions: SwaggerGlobalOptions) => HTMLString;
120
+ /**
121
+ * Type of request body for a route
122
+ */
123
+ type SwaggerBodyType = "json" | "form-data" | "urlencoded";
124
+ /**
125
+ * JSONSchema type for OpenAPI/AJV-compatible schemas
126
+ */
127
+ type JSONSchema = {
128
+ $id?: string;
129
+ $schema?: string;
130
+ type?: string | string[];
131
+ properties?: Record<string, JSONSchema>;
132
+ items?: JSONSchema | JSONSchema[];
133
+ required?: string[];
134
+ enum?: any[];
135
+ allOf?: JSONSchema[];
136
+ oneOf?: JSONSchema[];
137
+ anyOf?: JSONSchema[];
138
+ not?: JSONSchema;
139
+ additionalProperties?: boolean | JSONSchema;
140
+ description?: string;
141
+ format?: string;
142
+ default?: any;
143
+ title?: string;
144
+ definitions?: Record<string, JSONSchema>;
145
+ [key: string]: any;
146
+ };
147
+ /**
148
+ * Base options shared across all Swagger UI types
149
+ */
150
+ type SwaggerGlobalOptionsBase = {
151
+ /** The path to the swagger documentation, defaults to /docs for the UI and /docs/json for the raw json */
152
+ path?: string;
153
+ /** API title */
154
+ title?: string;
155
+ /** API description */
156
+ description?: string;
157
+ /** API version */
158
+ version?: string;
159
+ /** Server URLs */
160
+ servers?: string[];
161
+ /** Components (schemas, responses, parameters, etc.) */
162
+ components?: Record<string, any>;
163
+ /** Security schemes (OpenAPI 3.0 style) */
164
+ securitySchemes?: Record<string, Security>;
165
+ /** OpenID Connect configuration (discovery document) */
166
+ openIdConnect?: OpenIDConnectConfig;
167
+ /** API tags */
168
+ tags?: Record<string, any>;
169
+ /** Global security requirements */
170
+ security?: Security[];
171
+ /** External documentation */
172
+ externalDocs?: {
173
+ description?: string;
174
+ url: string;
175
+ };
176
+ /** Info object (detailed metadata) */
177
+ info?: {
178
+ title: string;
179
+ description?: string;
180
+ version: string;
181
+ termsOfService?: string;
182
+ contact?: {
183
+ name?: string;
184
+ url?: string;
185
+ email?: string;
186
+ };
187
+ license?: {
188
+ name: string;
189
+ url?: string;
190
+ };
191
+ };
192
+ /**
193
+ * OpenAPI models to be shown in the documentation. Must be valid OpenAPI/AJV JSONSchema objects.
194
+ */
195
+ models?: Record<string, JSONSchema> | JSONSchema[];
196
+ };
197
+ /**
198
+ * Global documentation options for the API (OpenAPI/Swagger style)
199
+ */
200
+ type SwaggerGlobalOptions = (SwaggerGlobalOptionsBase & {
201
+ /** Type of Swagger UI to use, one of 'standard', 'redoc', 'rapidoc', 'scalar', or 'elements'. Defaults to 'standard'. */
202
+ type?: Exclude<SwaggerUIType, "custom">;
203
+ }) | (SwaggerGlobalOptionsBase & {
204
+ /** Type of Swagger UI to use. When set to 'custom', customUIGenerator is required. */
205
+ type: "custom";
206
+ /** Custom UI generator function. Required when type is 'custom'. Must return a string of HTML that uses the given specUrl. */
207
+ customUIGenerator: CustomUIGenerator;
208
+ });
209
+ /**
210
+ * Route-specific documentation options (for individual endpoints)
211
+ */
212
+ type SwaggerRouteOptions = {
213
+ /** Service category where the route belongs to */
214
+ service?: string;
215
+ /** Name of the route */
216
+ name?: string;
217
+ /** Query parameters schema */
218
+ query?: ZodType;
219
+ /** Request body schema */
220
+ requestBody?: ZodType;
221
+ /** Responses for this route */
222
+ responses?: Record<number, ZodType>;
223
+ /** Errors for this route */
224
+ errors?: Record<number, ZodType>;
225
+ /** Security requirements for this route */
226
+ security?: Security[] | Security;
227
+ /** Description of the route */
228
+ description?: string;
229
+ /** Deprecated flag */
230
+ deprecated?: boolean;
231
+ /** Exclude from swagger */
232
+ excludeFromSwagger?: boolean;
233
+ /**
234
+ * The request body type for this route. Allowed values: 'json', 'form-data', 'urlencoded'. Defaults to 'json'.
235
+ */
236
+ bodyType?: SwaggerBodyType;
237
+ };
238
+ type OAuth2Flows = {
239
+ implicit?: OAuth2Flow;
240
+ authorizationCode?: OAuth2Flow;
241
+ clientCredentials?: OAuth2Flow;
242
+ password?: OAuth2Flow;
243
+ };
244
+ type OAuth2Flow = {
245
+ authorizationUrl?: string;
246
+ tokenUrl?: string;
247
+ refreshUrl?: string;
248
+ scopes: Record<string, string>;
249
+ };
250
+ type OpenIDConnectConfig = {
251
+ issuer: string;
252
+ authorizationEndpoint: string;
253
+ tokenEndpoint: string;
254
+ userinfoEndpoint?: string;
255
+ jwksUri: string;
256
+ endSessionEndpoint?: string;
257
+ introspectionEndpoint?: string;
258
+ revocationEndpoint?: string;
259
+ scopesSupported?: string[];
260
+ responseTypesSupported?: string[];
261
+ grantTypesSupported?: string[];
262
+ tokenEndpointAuthMethodsSupported?: string[];
263
+ subjectTypesSupported?: string[];
264
+ idTokenSigningAlgValuesSupported?: string[];
265
+ claimsSupported?: string[];
266
+ codeChallengeMethodsSupported?: string[];
267
+ };
268
+ type Security = BearerOptions | ApiKeyOptions | OAuth2Options | OpenIdConnectOptions;
269
+ type BearerOptions = {
270
+ type: "bearer";
271
+ bearerFormat?: string;
272
+ description?: string;
273
+ };
274
+ type ApiKeyOptions = {
275
+ type: "apiKey";
276
+ name: string;
277
+ in: "header" | "query" | "cookie";
278
+ description?: string;
279
+ };
280
+ type OAuth2Options = {
281
+ type: "oauth2";
282
+ flows: OAuth2Flows;
283
+ description?: string;
284
+ name?: string;
285
+ };
286
+ type OpenIdConnectOptions = {
287
+ type: "openIdConnect";
288
+ openIdConnectUrl: string;
289
+ description?: string;
290
+ name?: string;
291
+ };
292
+
293
+ /**
294
+ * Decorator to mark a class as a controller, routes defined in the controller will be registered at import time when calling the `listen` method.
295
+ * You can customize the path pattern for controller imports in the server options `controllerPatterns`
296
+ * @param path - The path pattern for the controller.
297
+ * @param swaggerOptions - The swagger options for the controller that will be applied to all routes defined in the controller. Controller options will override route options.
298
+ * @swagger If swagger is enabled, the default service name for all routes defined in the controller will be the controller name.
299
+ * @swagger For naming commodity, the default service name will remove the "Controller" suffix if it exists. e.g. "UserController" -> "User"
300
+ */
301
+ declare const controller: (path?: string, swaggerOptions?: SwaggerRouteOptions) => (target: any) => void;
302
+
303
+ type AjvInstance = InstanceType<typeof Ajv>;
304
+ type AjvCompileParams = Parameters<AjvInstance["compile"]>;
305
+
306
+ type SyncOrAsync<T = void> = T | Promise<T>;
307
+
308
+ interface AsyncLocalStorageContext {
309
+ }
310
+ type AsyncLocalStorageContextSetters<K extends keyof AsyncLocalStorageContext = keyof AsyncLocalStorageContext> = Record<K, (req: Request$1) => SyncOrAsync<AsyncLocalStorageContext[K]>>;
311
+
312
+ type StaticPluginOptions = {
313
+ /**
314
+ * The file system directory path where the assets are located
315
+ * @example "./tmp/assets" or "public"
316
+ */
317
+ source: string;
318
+ /**
319
+ * The URL path where the assets will be served
320
+ * @example "/assets" or "/public"
321
+ */
322
+ path: string;
323
+ };
324
+ type FileAllowedMimeType = "text/html" | "text/css" | "application/javascript" | "application/typescript" | "text/jsx" | "text/tsx" | "application/json" | "application/xml" | "application/yaml" | "text/csv" | "text/plain" | "text/markdown" | "image/png" | "image/jpeg" | "image/gif" | "image/svg+xml" | "image/x-icon" | "image/webp" | "image/avif" | "image/bmp" | "image/tiff" | "image/heic" | "image/heif" | "video/mp4" | "video/webm" | "video/x-msvideo" | "video/quicktime" | "video/x-matroska" | "video/x-ms-wmv" | "video/x-flv" | "video/x-m4v" | "video/mpeg" | "video/3gpp" | "audio/mpeg" | "audio/wav" | "audio/ogg" | "audio/flac" | "audio/aac" | "audio/mp4" | "audio/x-ms-wma" | "audio/opus" | "audio/midi" | "font/woff" | "font/woff2" | "font/ttf" | "font/otf" | "application/vnd.ms-fontobject" | "application/pdf" | "application/msword" | "application/vnd.openxmlformats-officedocument.wordprocessingml.document" | "application/vnd.ms-excel" | "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet" | "application/vnd.ms-powerpoint" | "application/vnd.openxmlformats-officedocument.presentationml.presentation" | "application/vnd.oasis.opendocument.text" | "application/vnd.oasis.opendocument.spreadsheet" | "application/vnd.oasis.opendocument.presentation" | "application/rtf" | "application/epub+zip" | "application/zip" | "application/x-tar" | "application/gzip" | "application/x-bzip2" | "application/x-xz" | "application/vnd.rar" | "application/x-7z-compressed" | "application/wasm" | "application/manifest+json" | "text/calendar" | "text/vcard" | "application/sql" | "application/x-sh" | "application/x-msdos-program" | "application/x-msdownload" | "application/octet-stream" | "application/x-iso9660-image" | "application/x-apple-diskimage" | "application/vnd.android.package-archive" | "application/java-archive" | "application/x-shockwave-flash";
325
+
326
+ type FormFile = {
327
+ /**
328
+ * The name of the form field.
329
+ */
330
+ formName: string;
331
+ /**
332
+ * The mime type of the file. (e.g. "image/png")
333
+ */
334
+ mimeType: string;
335
+ /**
336
+ * The size of the file in bytes.
337
+ */
338
+ size: number;
339
+ /**
340
+ * The temporary path of the file. Will be deleted after the request is processed automatically even in error cases.
341
+ */
342
+ tmpPath: string;
343
+ /**
344
+ * The original filename (including extension) as sent by the client
345
+ * (e.g. "avatar.png", "document.txt").
346
+ */
347
+ originalName: string;
348
+ };
349
+ type FilePluginOptions = {
350
+ /**
351
+ * The maximum size of each file.
352
+ * Supports formats like "5mb", "100kb".
353
+ * Example: "10mb", "500kb"
354
+ * Default: 1mb
355
+ */
356
+ maxFileSize?: `${number}mb` | `${number}kb`;
357
+ /**
358
+ * The maximum number of files allowed in a single request.
359
+ */
360
+ maxFiles?: number;
361
+ /**
362
+ * Allowed MIME types for uploaded files.
363
+ * If specified, only files with these MIME types will be accepted.
364
+ * Example: ['image/jpeg', 'image/png', 'application/pdf']
365
+ */
366
+ allowedMimeTypes?: (FileAllowedMimeType | (string & {}))[];
367
+ };
368
+
369
+ declare global {
370
+ interface Request {
371
+ params: Record<string, string>;
372
+ query: Record<string, string>;
373
+ }
374
+ }
375
+ declare class NativeRequest extends Request {
376
+ }
377
+
378
+ /**
379
+ * The request object.
380
+ * This is the main object that is passed to the handler function.
381
+ * It contains the request body, query parameters, files, cookies, etc.
382
+ * It also contains the validation methods.
383
+ */
384
+ declare class Request$1<Params extends Record<string, string> = any> extends NativeRequest {
385
+ static fromRequest(request: Request$1 | NativeRequest): Request$1;
386
+ private static compileAndValidate;
387
+ /**
388
+ * Enrich native request with validation methods.
389
+ */
390
+ static enrichRequest(request: Request$1): Request$1;
391
+ /**
392
+ * The context of the request. Can be augmented extending AsyncLocalStorageContext interface
393
+ * @asyncLocalStorage middleware is required
394
+ * @example
395
+ * ```ts
396
+ * declare module "balda" {
397
+ * interface AsyncLocalStorageContext {
398
+ * userId: string;
399
+ * }
400
+ * }
401
+ * ```
402
+ */
403
+ ctx: AsyncLocalStorageContext;
404
+ /**
405
+ * The file of the request.
406
+ * @fileParser middleware is required
407
+ */
408
+ file: (fieldName: string) => FormFile | null;
409
+ /**
410
+ * The cookies of the request.
411
+ * @cookie middleware is required
412
+ */
413
+ cookies: Record<string, string>;
414
+ /**
415
+ * The cookie of the request.
416
+ * @cookie middleware is required
417
+ */
418
+ cookie: (name: string) => string | undefined;
419
+ /**
420
+ * tells if the request has timed out.
421
+ * @timeout middleware is required
422
+ */
423
+ timeout?: boolean;
424
+ /**
425
+ * The session of the request. Uses cookies to send the session id
426
+ * @cookie middleware is required
427
+ * @session middleware is required
428
+ */
429
+ session?: Record<string, any>;
430
+ /**
431
+ * The session of the request. Uses cookies to send the session id
432
+ * @cookie middleware is required
433
+ * @session middleware is required
434
+ */
435
+ saveSession: () => Promise<void>;
436
+ /**
437
+ * The session of the request.
438
+ * @cookie middleware is required
439
+ * @session middleware is required
440
+ */
441
+ destroySession: () => Promise<void>;
442
+ /**
443
+ * The ip address of the request.
444
+ * Tries to get the ip address from the `x-forwarded-for` header. If not available, it will use the remote address from the request.
445
+ */
446
+ ip?: string;
447
+ /**
448
+ * The files of the request. Only available for multipart/form-data requests and if the file parser middleware is used.
449
+ */
450
+ files: FormFile[];
451
+ /**
452
+ * The parameters of the request. Can be typed with a generic in the Request object
453
+ * @example
454
+ * ```ts
455
+ * Request<{ id: string }>
456
+ */
457
+ params: Params;
458
+ /**
459
+ * The query parameters of the request.
460
+ */
461
+ query: Record<string, string>;
462
+ /**
463
+ * The raw body of the request. Only available for POST, PUT, PATCH and DELETE requests.
464
+ */
465
+ rawBody?: ArrayBuffer;
466
+ private _id;
467
+ /**
468
+ * The id of the request.
469
+ */
470
+ get id(): string;
471
+ set id(value: string);
472
+ /**
473
+ * The parsed body of the request
474
+ */
475
+ body: any;
476
+ /**
477
+ * The validated body of the request.
478
+ * @param inputSchema - The schema to validate the body against (Zod schema or JSON Schema).
479
+ * @param safe - If true, the function will return the original body if the validation fails instead of throwing an error.
480
+ */
481
+ validate(inputSchema: ZodAny | AjvCompileParams[0], safe?: boolean): any;
482
+ /**
483
+ * Validates the query string of the request.
484
+ * @param inputSchema - The schema to validate the query against (Zod schema or JSON Schema).
485
+ * @param safe - If true, the function will return undefined if the validation fails instead of throwing an error.
486
+ */
487
+ validateQuery(inputSchema: ZodAny | AjvCompileParams[0], safe?: boolean): any;
488
+ /**
489
+ * Validates the body and query string of the request.
490
+ * @param inputSchema - The schema to validate against (Zod schema or JSON Schema).
491
+ * @param safe - If true, the function will return undefined if the validation fails instead of throwing an error.
492
+ */
493
+ validateAll(inputSchema: ZodAny | AjvCompileParams[0], safe?: boolean): any;
494
+ }
495
+
496
+ /**
497
+ * Cookie options for setting cookies
498
+ */
499
+ type CookieOptions = {
500
+ /**
501
+ * Domain for the cookie
502
+ */
503
+ domain?: string;
504
+ /**
505
+ * Path for the cookie
506
+ */
507
+ path?: string;
508
+ /**
509
+ * Expiration date for the cookie
510
+ */
511
+ expires?: Date;
512
+ /**
513
+ * Max age in seconds for the cookie
514
+ */
515
+ maxAge?: number;
516
+ /**
517
+ * Whether the cookie is secure (HTTPS only)
518
+ * @default true
519
+ *
520
+ * ⚠️ Should be `true` in production to prevent transmission over HTTP
521
+ */
522
+ secure?: boolean;
523
+ /**
524
+ * Whether the cookie is HTTP only (prevents JavaScript access)
525
+ * @default true
526
+ *
527
+ * ✅ Recommended: `true` to prevent XSS attacks
528
+ */
529
+ httpOnly?: boolean;
530
+ /**
531
+ * SameSite attribute for the cookie
532
+ *
533
+ * - "Strict": Most secure, cookie not sent on cross-site requests
534
+ * - "Lax": Balanced, cookie sent on top-level navigation
535
+ * - "None": Least secure, requires secure=true
536
+ *
537
+ * ✅ Recommended: "Strict" for auth cookies
538
+ */
539
+ sameSite?: "Strict" | "Lax" | "None";
540
+ /**
541
+ * Whether the cookie should be signed
542
+ */
543
+ signed?: boolean;
544
+ /**
545
+ * Priority for the cookie
546
+ */
547
+ priority?: "Low" | "Medium" | "High";
548
+ };
549
+ /**
550
+ * Options for the cookie middleware
551
+ */
552
+ type CookieMiddlewareOptions = {
553
+ /**
554
+ * Secret key for signing cookies (required if using signed cookies)
555
+ */
556
+ secret?: string;
557
+ /**
558
+ * Default options for all cookies set by this middleware
559
+ */
560
+ defaults?: CookieOptions;
561
+ /**
562
+ * Whether to enable cookie parsing (defaults to true)
563
+ */
564
+ parse?: boolean;
565
+ /**
566
+ * Whether to enable cookie signing (defaults to false)
567
+ */
568
+ sign?: boolean;
569
+ };
570
+
571
+ /**
572
+ * The response object.
573
+ * This is the main object that is passed to the handler function.
574
+ * It contains the response body, status, headers, etc.
575
+ * It also contains the methods to send the response.
576
+ */
577
+ declare class Response$1 {
578
+ /**
579
+ * The node http response object available only on the node runtime, useful for direct response manipulation
580
+ * @warning undefined on other runtimes since they already use Web API Response object
581
+ */
582
+ nodeResponse: ServerResponse;
583
+ /**
584
+ * The status of the response
585
+ */
586
+ responseStatus: number;
587
+ /**
588
+ * The headers of the response
589
+ */
590
+ headers: Record<string, string>;
591
+ /**
592
+ * The body of the response
593
+ */
594
+ private body;
595
+ constructor(status?: number);
596
+ /**
597
+ * Set a header for the response
598
+ */
599
+ setHeader(key: string, value: string): this;
600
+ /**
601
+ * Set the status of the response, status defaults to 200
602
+ */
603
+ status(status: number): this;
604
+ /**
605
+ * Send a response with the given body, tries to determine the content type based on the body type, status defaults to 200
606
+ * @warning If cannot determine the content type, it will be sent as is
607
+ */
608
+ send(body: any): void;
609
+ /**
610
+ * Send a response with the given body without any content type or encoding (as is), status defaults to 200
611
+ */
612
+ raw(body: any): void;
613
+ /**
614
+ * Send a response with the given text, status defaults to 200
615
+ */
616
+ text(body: string): void;
617
+ /**
618
+ * Send a response with the given JSON, status defaults to 200
619
+ */
620
+ json<T extends Record<string, unknown> | Array<unknown>>(body: T): void;
621
+ /**
622
+ * Send a response with the given HTML, status defaults to 200
623
+ */
624
+ html(htmlString: string): void;
625
+ /**
626
+ * Send a response with the given XML, status defaults to 200
627
+ */
628
+ xml(body: string): void;
629
+ /**
630
+ * Send a response with the given binary with Content-Type of application/octet-stream header, status defaults to 200
631
+ */
632
+ download(body: Uint8Array | Buffer): void;
633
+ /**
634
+ * Send a response with the given file content, status defaults to 200
635
+ * @param options only affects node and bun environment
636
+ */
637
+ file(pathToFile: string, options?: {
638
+ encoding?: string;
639
+ flag?: string;
640
+ }): void;
641
+ /**
642
+ * 2XX Success
643
+ */
644
+ /**
645
+ * 200 OK
646
+ */
647
+ ok(body?: any): void;
648
+ /**
649
+ * 201 Created
650
+ */
651
+ created(body?: any): void;
652
+ /**
653
+ * 202 Accepted
654
+ */
655
+ accepted(body?: any): void;
656
+ /**
657
+ * 204 No Content
658
+ */
659
+ noContent(): void;
660
+ /**
661
+ * 206 Partial Content
662
+ */
663
+ partialContent(body?: any): void;
664
+ /**
665
+ * 3XX Redirection
666
+ */
667
+ /**
668
+ * 300 Multiple Choices
669
+ */
670
+ multipleChoices(url: string): void;
671
+ redirect(url: string): void;
672
+ /**
673
+ * 301 Moved Permanently
674
+ */
675
+ movedPermanently(url: string): void;
676
+ /**
677
+ * 302 Found (Temporary Redirect)
678
+ */
679
+ found(url: string): void;
680
+ /**
681
+ * 303 See Other
682
+ */
683
+ seeOther(url: string): void;
684
+ /**
685
+ * 304 Not Modified
686
+ */
687
+ notModified(): void;
688
+ /**
689
+ * 307 Temporary Redirect
690
+ */
691
+ temporaryRedirect(url: string): void;
692
+ /**
693
+ * 308 Permanent Redirect
694
+ */
695
+ permanentRedirect(url: string): void;
696
+ /**
697
+ * 4XX Client Errors
698
+ */
699
+ /**
700
+ * 400 Bad Request
701
+ */
702
+ badRequest(body?: any): void;
703
+ /**
704
+ * 401 Unauthorized
705
+ */
706
+ unauthorized(body?: any): void;
707
+ /**
708
+ * 403 Forbidden
709
+ */
710
+ forbidden(body?: any): void;
711
+ /**
712
+ * 404 Not Found
713
+ */
714
+ notFound(body?: any): void;
715
+ /**
716
+ * 405 Method Not Allowed
717
+ */
718
+ methodNotAllowed(body?: any): void;
719
+ /**
720
+ * 406 Not Acceptable
721
+ */
722
+ notAcceptable(body?: any): void;
723
+ /**
724
+ * 409 Conflict
725
+ */
726
+ conflict(body?: any): void;
727
+ /**
728
+ * 410 Gone
729
+ */
730
+ gone(body?: any): void;
731
+ /**
732
+ * 413 Payload Too Large
733
+ */
734
+ payloadTooLarge(body?: any): void;
735
+ /**
736
+ * 415 Unsupported Media Type
737
+ */
738
+ unsupportedMediaType(body?: any): void;
739
+ /**
740
+ * 422 Unprocessable Entity
741
+ */
742
+ unprocessableEntity(body?: any): void;
743
+ /**
744
+ * 429 Too Many Requests
745
+ */
746
+ tooManyRequests(body?: any): void;
747
+ /**
748
+ * 5XX Server Errors
749
+ */
750
+ internalServerError(body?: any): void;
751
+ /**
752
+ * 501 Not Implemented
753
+ */
754
+ notImplemented(body?: any): void;
755
+ /**
756
+ * 502 Bad Gateway
757
+ */
758
+ badGateway(body?: any): void;
759
+ /**
760
+ * 503 Service Unavailable
761
+ */
762
+ serviceUnavailable(body?: any): void;
763
+ /**
764
+ * 504 Gateway Timeout
765
+ */
766
+ gatewayTimeout(body?: any): void;
767
+ /**
768
+ * 505 HTTP Version Not Supported
769
+ */
770
+ httpVersionNotSupported(body?: any): void;
771
+ /**
772
+ * Set a cookie for the response, cookie middleware must be registered in order to use this function
773
+ */
774
+ cookie?(_name: string, _value: string, _options?: CookieOptions): void;
775
+ /**
776
+ * Clear a cookie for the response, cookie middleware must be registered in order to use this function
777
+ */
778
+ clearCookie?(_name: string, _options?: CookieOptions): void;
779
+ /**
780
+ * Stream a response using an async generator or ReadableStream
781
+ * Sets appropriate headers for Server-Sent Events by default
782
+ */
783
+ stream(source: AsyncGenerator<any> | Generator<any> | ReadableStream, options?: {
784
+ customHeaders?: Record<string, string>;
785
+ }): void;
786
+ /**
787
+ * Get the body of the response
788
+ */
789
+ getBody(): any;
790
+ }
791
+
792
+ type DelHandler = (req: Request$1, res: Response$1, ...args: any[]) => any;
793
+ /**
794
+ * Decorator to mark an handler for a DELETE request
795
+ * @param path - The path of the route
796
+ * @param options - The options for the route
797
+ * @warning Must receive the request and response as the first two arguments or it might not work as expected.
798
+ * @example
799
+ * ```ts
800
+ * import { del, controller, Request, Response } from "balda";
801
+ *
802
+ * @controller("/api")
803
+ * class MyController {
804
+ * @del("/")
805
+ * async handler(req: Request, res: Response) {
806
+ * // ...
807
+ * }
808
+ * }
809
+ * ```
810
+ */
811
+ declare const del: (path: string, options?: SwaggerRouteOptions) => <T extends DelHandler>(target: any, propertyKey: string, descriptor: PropertyDescriptor) => TypedPropertyDescriptor<T>;
812
+
813
+ type GetHandler = (req: Request$1, res: Response$1, ...args: any[]) => any;
814
+ /**
815
+ * Decorator to mark an handler for a GET request
816
+ * @param path - The path of the route
817
+ * @param options - The options for the route
818
+ * @warning Must receive the request and response as the first two arguments or it might not work as expected.
819
+ * @example
820
+ * ```ts
821
+ * import { get, controller, Request, Response } from "balda";
822
+ *
823
+ * @controller("/api")
824
+ * class MyController {
825
+ * @get("/")
826
+ * async handler(req: Request, res: Response) {
827
+ * // ...
828
+ * }
829
+ * }
830
+ * ```
831
+ */
832
+ declare const get: (path: string, options?: SwaggerRouteOptions) => <T extends GetHandler>(target: any, propertyKey: string, descriptor: PropertyDescriptor) => TypedPropertyDescriptor<T>;
833
+
834
+ type PatchHandler = (req: Request$1, res: Response$1, ...args: any[]) => any;
835
+ /**
836
+ * Decorator to mark an handler for a PATCH request
837
+ * @param path - The path of the route
838
+ * @param options - The options for the route
839
+ * @warning Must receive the request and response as the first two arguments or it might not work as expected.
840
+ * @example
841
+ * ```ts
842
+ * import { patch, controller, Request, Response } from "balda";
843
+ *
844
+ * @controller("/api")
845
+ * class MyController {
846
+ * @patch("/")
847
+ * async handler(req: Request, res: Response) {
848
+ * // ...
849
+ * }
850
+ * }
851
+ * ```
852
+ */
853
+ declare const patch: (path: string, options?: SwaggerRouteOptions) => <T extends PatchHandler>(target: any, propertyKey: string, descriptor: PropertyDescriptor) => TypedPropertyDescriptor<T>;
854
+
855
+ type PostHandler = (req: Request$1, res: Response$1, ...args: any[]) => any;
856
+ /**
857
+ * Decorator to mark an handler for a POST request
858
+ * @param path - The path of the route
859
+ * @param options - The options for the route
860
+ * @warning Must receive the request and response as the first two arguments or it might not work as expected.
861
+ * @example
862
+ * ```ts
863
+ * import { post, controller, Request, Response } from "balda";
864
+ *
865
+ * @controller("/api")
866
+ * class MyController {
867
+ * @post("/")
868
+ * async handler(req: Request, res: Response) {
869
+ * // ...
870
+ * }
871
+ * }
872
+ * ```
873
+ */
874
+ declare const post: (path: string, options?: SwaggerRouteOptions) => <T extends PostHandler>(target: any, propertyKey: string, descriptor: PropertyDescriptor) => TypedPropertyDescriptor<T>;
875
+
876
+ type PutHandler = (req: Request$1, res: Response$1, ...args: any[]) => any;
877
+ /**
878
+ * Decorator to mark an handler for a PUT request
879
+ * @param path - The path of the route
880
+ * @param options - The options for the route
881
+ * @warning Must receive the request and response as the first two arguments or it might not work as expected.
882
+ * @example
883
+ * ```ts
884
+ * import { put, controller, Request, Response } from "balda";
885
+ *
886
+ * @controller("/api")
887
+ * class MyController {
888
+ * @put("/")
889
+ * async handler(req: Request, res: Response) {
890
+ * // ...
891
+ * }
892
+ */
893
+ declare const put: (path: string, options?: SwaggerRouteOptions) => <T extends PutHandler>(target: any, propertyKey: string, descriptor: PropertyDescriptor) => TypedPropertyDescriptor<T>;
894
+
895
+ type GraphQLSchemaInput = Parameters<typeof createSchema>[0];
896
+ type GraphQLTypeDef = GraphQLSchemaInput["typeDefs"];
897
+ type GraphQLResolvers = GraphQLSchemaInput["resolvers"];
898
+ interface GraphQLContext {
899
+ }
900
+ type GraphQLResolverFunction<TContext = GraphQLContext> = (parent: unknown, args: Record<string, unknown>, context: TContext, info: unknown) => unknown | Promise<unknown>;
901
+ type GraphQLResolverMap<TContext = GraphQLContext> = Record<string, GraphQLResolverFunction<TContext> | Record<string, unknown>>;
902
+ type GraphQLOptions = {
903
+ schema?: GraphQLSchemaInput;
904
+ yogaOptions?: Parameters<typeof createYoga>[0];
905
+ };
906
+ type GraphQLResolverType = "Query" | "Mutation" | "Subscription";
907
+
908
+ declare class GraphQL {
909
+ private schemaOptions;
910
+ private yogaOptions;
911
+ isEnabled: boolean;
912
+ constructor(options?: GraphQLOptions);
913
+ getSchema(createSchemaFn: typeof createSchema): GraphQLSchema;
914
+ getYogaOptions(): Parameters<typeof createYoga>[0];
915
+ /**
916
+ * Add a type definition to the schema
917
+ */
918
+ addTypeDef(typeDef: GraphQLTypeDef): void;
919
+ /**
920
+ * Add a resolver to the schema
921
+ * @param type - The resolver type (Query, Mutation, Subscription, or a custom type name)
922
+ * @param resolvers - An object mapping field names to resolver functions, or a full resolver object
923
+ */
924
+ addResolver(type: GraphQLResolverType, resolvers: GraphQLResolverMap): void;
925
+ addResolver(resolver: GraphQLResolvers): void;
926
+ addResolver(type: string, resolvers: GraphQLResolverMap): void;
927
+ private initializeConfiguration;
928
+ private createDisabledConfiguration;
929
+ private createEnabledConfiguration;
930
+ private resolveSchemaOptions;
931
+ private resolveYogaOptions;
932
+ private addResolverByType;
933
+ private ensureResolversInitialized;
934
+ private mergeResolverIntoObject;
935
+ private addFullResolver;
936
+ private addResolverArray;
937
+ private addResolverObject;
938
+ private addTypeDefArray;
939
+ private ensureTypeDefsArray;
940
+ }
941
+
942
+ declare class MockResponse<T = any> {
943
+ private readonly response;
944
+ constructor(response: Response$1);
945
+ body(): T;
946
+ statusCode(): number;
947
+ headers(): Record<string, string>;
948
+ assertStatus(status: number): this;
949
+ assertHeader(header: string, value: string): this;
950
+ assertHeaderExists(header: string): this;
951
+ assertHeaderNotExists(header: string): this;
952
+ assertBodySubset(subset: Partial<T>): this;
953
+ assertBodyDeepEqual(expected: T): this;
954
+ assertBodyNotSubset(subset: Partial<T>): this;
955
+ assertBodyNotDeepEqual(expected: T): this;
956
+ assertCustom(assertion: (response: Response$1) => void): this;
957
+ private assertSubset;
958
+ private assertDeepEqual;
959
+ private assertNotSubset;
960
+ private assertNotDeepEqual;
961
+ private assertArraySubset;
962
+ private assertArrayDeepEqual;
963
+ private isObject;
964
+ }
965
+
966
+ /**
967
+ * The options for the mock server, only one of body, formData, urlencoded can be provided
968
+ */
969
+ interface MockServerOptions {
970
+ /**
971
+ * The body of the request, if formData is provided, it will be ignored
972
+ */
973
+ body?: any;
974
+ /**
975
+ * The form data of the request
976
+ */
977
+ formData?: FormData;
978
+ /**
979
+ * The urlencoded body of the request
980
+ */
981
+ urlencoded?: Record<string, string>;
982
+ /**
983
+ * The headers of the request
984
+ */
985
+ headers?: Record<string, string>;
986
+ /**
987
+ * The query parameters of the request, if provided, they will be merged with the query parameters from the path (precedence is given to the query parameters provided here)
988
+ */
989
+ query?: Record<string, string>;
990
+ /**
991
+ * The cookies of the request
992
+ */
993
+ cookies?: Record<string, string>;
994
+ /**
995
+ * The ip of the request
996
+ */
997
+ ip?: string;
998
+ }
999
+
1000
+ /**
1001
+ * Singleton that handles the routing of requests to the appropriate handler(s).
1002
+ */
1003
+ declare class Router {
1004
+ private trees;
1005
+ private routes;
1006
+ private middlewares;
1007
+ private basePath;
1008
+ /**
1009
+ * Create a new router with an optional base path and default middlewares.
1010
+ * Base path is normalized so it never produces duplicate slashes and never ends with a trailing slash (except root).
1011
+ */
1012
+ constructor(basePath?: string, middlewares?: ServerRouteMiddleware[]);
1013
+ /** Returns a shallow copy of all registered routes. */
1014
+ getRoutes(): Route[];
1015
+ /**
1016
+ * Add or update a route
1017
+ * @internal
1018
+ */
1019
+ addOrUpdate(method: HttpMethod, path: string, middleware: ServerRouteMiddleware[], handler: ServerRouteHandler, swaggerOptions?: SwaggerRouteOptions): void;
1020
+ /**
1021
+ * Find the matching route for the given HTTP method and path.
1022
+ * Returns the resolved middleware chain, handler, and extracted params; or null if not found.
1023
+ */
1024
+ find(method: string, rawPath: string): {
1025
+ middleware: ServerRouteMiddleware[];
1026
+ handler: ServerRouteHandler;
1027
+ params: Params;
1028
+ } | null;
1029
+ /**
1030
+ * Register a GET route under this router's base path.
1031
+ */
1032
+ get(path: string, handler: ServerRouteHandler, swaggerOptions?: SwaggerRouteOptions): void;
1033
+ get(path: string, middleware: ServerRouteMiddleware | ServerRouteMiddleware[], handler: ServerRouteHandler, swaggerOptions?: SwaggerRouteOptions): void;
1034
+ /**
1035
+ * Register a POST route under this router's base path.
1036
+ */
1037
+ post(path: string, handler: ServerRouteHandler, swaggerOptions?: SwaggerRouteOptions): void;
1038
+ post(path: string, middleware: ServerRouteMiddleware | ServerRouteMiddleware[], handler: ServerRouteHandler, swaggerOptions?: SwaggerRouteOptions): void;
1039
+ /**
1040
+ * Register a PATCH route under this router's base path.
1041
+ */
1042
+ patch(path: string, handler: ServerRouteHandler, swaggerOptions?: SwaggerRouteOptions): void;
1043
+ patch(path: string, middleware: ServerRouteMiddleware | ServerRouteMiddleware[], handler: ServerRouteHandler, swaggerOptions?: SwaggerRouteOptions): void;
1044
+ /**
1045
+ * Register a PUT route under this router's base path.
1046
+ */
1047
+ put(path: string, handler: ServerRouteHandler, swaggerOptions?: SwaggerRouteOptions): void;
1048
+ put(path: string, middleware: ServerRouteMiddleware | ServerRouteMiddleware[], handler: ServerRouteHandler, swaggerOptions?: SwaggerRouteOptions): void;
1049
+ /**
1050
+ * Register a DELETE route under this router's base path.
1051
+ */
1052
+ delete(path: string, handler: ServerRouteHandler, swaggerOptions?: SwaggerRouteOptions): void;
1053
+ delete(path: string, middleware: ServerRouteMiddleware | ServerRouteMiddleware[], handler: ServerRouteHandler, swaggerOptions?: SwaggerRouteOptions): void;
1054
+ /**
1055
+ * Register an OPTIONS route under this router's base path.
1056
+ */
1057
+ options(path: string, handler: ServerRouteHandler, swaggerOptions?: SwaggerRouteOptions): void;
1058
+ options(path: string, middleware: ServerRouteMiddleware | ServerRouteMiddleware[], handler: ServerRouteHandler, swaggerOptions?: SwaggerRouteOptions): void;
1059
+ /**
1060
+ * Register an HEAD route under this router's base path.
1061
+ */
1062
+ head(path: string, handler: ServerRouteHandler, swaggerOptions?: SwaggerRouteOptions): void;
1063
+ head(path: string, middleware: ServerRouteMiddleware | ServerRouteMiddleware[], handler: ServerRouteHandler, swaggerOptions?: SwaggerRouteOptions): void;
1064
+ /**
1065
+ * Create a grouped router that shares a base path and middlewares.
1066
+ * The callback receives a child router where routes are defined; routes
1067
+ * are then merged back into the parent with the composed base path and middlewares.
1068
+ */
1069
+ group(path: string, middleware: ServerRouteMiddleware[] | ServerRouteMiddleware, cb: (router: Router) => void): void;
1070
+ group(path: string, cb: (router: Router) => void): void;
1071
+ /**
1072
+ * Apply global middlewares to all routes
1073
+ * @param middlewares - The middlewares to apply
1074
+ * @internal
1075
+ */
1076
+ applyGlobalMiddlewaresToAllRoutes(middlewares: ServerRouteMiddleware[]): void;
1077
+ private normalizeBasePath;
1078
+ private joinPath;
1079
+ }
1080
+
1081
+ type Params = Record<string, string>;
1082
+ interface Route {
1083
+ method: string;
1084
+ path: string;
1085
+ middleware: ServerRouteMiddleware[];
1086
+ handler: ServerRouteHandler;
1087
+ swaggerOptions?: SwaggerRouteOptions;
1088
+ }
1089
+ /**
1090
+ * The client router is a subset of the router that is used to define routes on library level by the end user.
1091
+ */
1092
+ type ClientRouter = Omit<Router, "applyGlobalMiddlewaresToAllRoutes" | "addOrUpdate">;
1093
+
1094
+ /**
1095
+ * The server class that is used to create and manage the server
1096
+ */
1097
+ declare class Server<H extends NodeHttpClient = NodeHttpClient> implements ServerInterface {
1098
+ isListening: boolean;
1099
+ isProduction: boolean;
1100
+ graphql: GraphQL;
1101
+ readonly router: ClientRouter;
1102
+ private wasInitialized;
1103
+ private serverConnector;
1104
+ private globalMiddlewares;
1105
+ private serverOptions;
1106
+ private controllerImportBlacklistedPaths;
1107
+ private notFoundHandler?;
1108
+ private readonly nativeEnv;
1109
+ private httpsOptions?;
1110
+ /**
1111
+ * The constructor for the server
1112
+ * @warning Routes will only be defined after calling the `listen` method so you're free to define middlewares before calling it
1113
+ * @param options - The options for the server
1114
+ * @param options.port - The port to listen on, if not provided, it will use the PORT environment variable, if not provided, it will default to 80
1115
+ * @param options.host - The hostname to listen on, if not provided, it will use the HOST environment variable, if not provided, it will default to 0.0.0.0
1116
+ * @param options.controllerPatterns - The patterns to match for controllers, defaults to an empty array
1117
+ * @param options.plugins - The plugins to apply to the server, by default no plugins are applied, plugins are applied in the order they are defined in the options
1118
+ * @param options.logger - The logger to use for the server, by default a default logger is used
1119
+ * @param options.tapOptions - Options fetch to the runtime server before the server is up and running
1120
+ */
1121
+ constructor(options?: ServerOptions<H>);
1122
+ get url(): string;
1123
+ get port(): number;
1124
+ get host(): string;
1125
+ get routes(): Route[];
1126
+ hash(data: string): Promise<string>;
1127
+ compareHash(hash: string, data: string): Promise<boolean>;
1128
+ getEnvironment(): Record<string, string>;
1129
+ tmpDir(...append: string[]): string;
1130
+ mkdir(path: string, options?: {
1131
+ recursive?: boolean;
1132
+ mode?: number | string;
1133
+ }): Promise<void>;
1134
+ get(path: string, handler: ServerRouteHandler): void;
1135
+ get(path: string, options: StandardMethodOptions, handler: ServerRouteHandler): void;
1136
+ post(path: string, handler: ServerRouteHandler): void;
1137
+ post(path: string, options: StandardMethodOptions, handler: ServerRouteHandler): void;
1138
+ patch(path: string, handler: ServerRouteHandler): void;
1139
+ patch(path: string, options: StandardMethodOptions, handler: ServerRouteHandler): void;
1140
+ put(path: string, handler: ServerRouteHandler): void;
1141
+ put(path: string, options: StandardMethodOptions, handler: ServerRouteHandler): void;
1142
+ delete(path: string, handler: ServerRouteHandler): void;
1143
+ delete(path: string, options: StandardMethodOptions, handler: ServerRouteHandler): void;
1144
+ options(path: string, handler: ServerRouteHandler): void;
1145
+ options(path: string, options: StandardMethodOptions, handler: ServerRouteHandler): void;
1146
+ head(path: string, handler: ServerRouteHandler): void;
1147
+ head(path: string, options: StandardMethodOptions, handler: ServerRouteHandler): void;
1148
+ group(path: string, middleware: ServerRouteMiddleware[] | ServerRouteMiddleware, cb: (router: ClientRouter) => void): void;
1149
+ group(path: string, cb: (router: ClientRouter) => void): void;
1150
+ getNodeServer(): RuntimeServerMap<"node", H>;
1151
+ getBunServer(): RuntimeServerMap<"bun">;
1152
+ getDenoServer(): RuntimeServerMap<"deno">;
1153
+ embed(key: string, value: any): void;
1154
+ exit(code?: number): void;
1155
+ on(event: SignalEvent, cb: () => SyncOrAsync): void;
1156
+ on(event: string, cb: () => SyncOrAsync): void;
1157
+ once(event: SignalEvent, cb: () => SyncOrAsync): void;
1158
+ once(event: string, cb: () => SyncOrAsync): void;
1159
+ use(...middlewares: ServerRouteMiddleware[]): void;
1160
+ useExpress(pathOrMiddleware: string | RequestHandler | Router$1, maybeMiddleware?: RequestHandler | Router$1): void;
1161
+ expressMiddleware(middleware: RequestHandler): ServerRouteMiddleware;
1162
+ mountExpressRouter(basePath: string, expressRouter: Router$1): void;
1163
+ setErrorHandler(errorHandler?: ServerErrorHandler): void;
1164
+ /**
1165
+ * Sets a custom handler for 404 Not Found responses.
1166
+ * If not set, the default RouteNotFoundError will be used.
1167
+ *
1168
+ * @param notFoundHandler - Optional handler to customize 404 responses
1169
+ * @example
1170
+ * server.setNotFoundHandler((req, res) => {
1171
+ * res.status(404).json({ error: "Custom not found message" });
1172
+ * });
1173
+ */
1174
+ setNotFoundHandler(notFoundHandler?: ServerRouteHandler): void;
1175
+ listen(cb?: ServerListenCallback): void;
1176
+ close(): Promise<void>;
1177
+ /**
1178
+ * Returns a mock server instance that can be used to test the server without starting it
1179
+ * It will import the controllers and apply the plugins to the mock server
1180
+ * @param options - The options for the mock server
1181
+ * @param options.controllerPatterns - Custom controller patterns to import if the mock server must not be initialized with the same controller patterns as the server
1182
+ */
1183
+ getMockServer(options?: Pick<ServerOptions, "controllerPatterns">): Promise<MockServer>;
1184
+ private importControllers;
1185
+ private extractOptionsAndHandlerFromRouteRegistration;
1186
+ private applyPlugins;
1187
+ /**
1188
+ * Initializes the server by importing the controllers and applying the plugins, it's idempotent, it will not re-import the controllers or apply the plugins if the server was already initialized (e.g. mockServer init)
1189
+ * @internal
1190
+ */
1191
+ private bootstrap;
1192
+ /**
1193
+ * Handles not found routes by delegating to custom handler or default error response
1194
+ * Checks if the path exists for other methods and returns 405 if so
1195
+ * @internal
1196
+ */
1197
+ private handleNotFound;
1198
+ /**
1199
+ * Registers a not found route for all routes that are not defined
1200
+ * @internal
1201
+ */
1202
+ private registerNotFoundRoutes;
1203
+ }
1204
+
1205
+ /**
1206
+ * Allows to mock server requests without needing to start the server, useful for testing purposes
1207
+ */
1208
+ declare class MockServer {
1209
+ readonly server: Server<NodeHttpClient>;
1210
+ constructor(server: Server<NodeHttpClient>);
1211
+ /**
1212
+ * Simulates an HTTP request without making an actual network call, useful for testing purposes
1213
+ * Executes the middleware chain and handler of the route
1214
+ * @param method - The HTTP method (GET, POST, PUT, DELETE, PATCH)
1215
+ * @param path - The request path
1216
+ * @param options - Request options including body, headers, query params, etc.
1217
+ * @throws {Error} - If more than one of body, formData, urlencoded is provided
1218
+ */
1219
+ request<T = any>(method: HttpMethod, path: string, options?: MockServerOptions): Promise<MockResponse<T>>;
1220
+ get<T = any>(path: string, options?: Omit<MockServerOptions, "body" | "formData" | "urlencoded">): Promise<MockResponse<T>>;
1221
+ post<T = any>(path: string, options?: MockServerOptions): Promise<MockResponse<T>>;
1222
+ put<T = any>(path: string, options?: MockServerOptions): Promise<MockResponse<T>>;
1223
+ patch<T = any>(path: string, options?: MockServerOptions): Promise<MockResponse<T>>;
1224
+ delete<T = any>(path: string, options?: Omit<MockServerOptions, "body" | "formData">): Promise<MockResponse<T>>;
1225
+ /**
1226
+ * Converts FormData to a proper multipart/form-data body with boundaries
1227
+ */
1228
+ private formDataToMultipart;
1229
+ private validateOptions;
1230
+ }
1231
+
1232
+ type CompressionOptions = {
1233
+ /**
1234
+ * Minimum response size in bytes to trigger compression
1235
+ * Default: 1024 (1KB)
1236
+ */
1237
+ threshold?: number;
1238
+ /**
1239
+ * Compression level (0-9)
1240
+ * 0 = no compression, 9 = maximum compression
1241
+ * Default: 6
1242
+ */
1243
+ level?: number;
1244
+ /**
1245
+ * Content types to compress (regex patterns)
1246
+ * Default: common compressible types (text, json, xml, javascript, etc.)
1247
+ */
1248
+ filter?: RegExp[];
1249
+ };
1250
+
1251
+ type CorsMethods = "GET" | "POST" | "PUT" | "DELETE" | "OPTIONS" | "PATCH" | "HEAD";
1252
+ /**
1253
+ * Options for CORS middleware, similar to Express.js
1254
+ */
1255
+ type CorsOptions = {
1256
+ /**
1257
+ * Configures the Access-Control-Allow-Origin CORS header.
1258
+ *
1259
+ * ⚠️ WARNING: The default value '*' allows ALL origins, which is insecure for production.
1260
+ *
1261
+ * For production, explicitly set allowed origins:
1262
+ * - Single origin: 'https://example.com'
1263
+ * - Multiple origins: ['https://example.com', 'https://app.example.com']
1264
+ * - Pattern matching: /^https:\/\/.*\.example\.com$/
1265
+ *
1266
+ * Defaults to '*' (allows all origins) - only suitable for development/public APIs.
1267
+ */
1268
+ origin?: string | RegExp | (string | RegExp)[];
1269
+ /**
1270
+ * Configures the Access-Control-Allow-Methods CORS header. Defaults to 'GET,HEAD,PUT,PATCH,POST,DELETE'.
1271
+ */
1272
+ methods?: CorsMethods[] | string;
1273
+ /**
1274
+ * Configures the Access-Control-Allow-Headers CORS header. Defaults to allowing all requested headers.
1275
+ */
1276
+ allowedHeaders?: string[] | string;
1277
+ /**
1278
+ * Configures the Access-Control-Expose-Headers CORS header. Defaults to none.
1279
+ */
1280
+ exposedHeaders?: string[] | string;
1281
+ /**
1282
+ * Configures the Access-Control-Allow-Credentials CORS header. Defaults to false.
1283
+ */
1284
+ credentials?: boolean;
1285
+ /**
1286
+ * Configures the Access-Control-Max-Age CORS header. Defaults to undefined (not sent).
1287
+ */
1288
+ maxAge?: number;
1289
+ /**
1290
+ * Pass the CORS preflight response to the next handler. Defaults to false (ends response).
1291
+ */
1292
+ preflightContinue?: boolean;
1293
+ /**
1294
+ * Provides a status code to use for successful OPTIONS requests, if preflightContinue is false. Defaults to 204.
1295
+ */
1296
+ optionsSuccessStatus?: number;
1297
+ };
1298
+
1299
+ type ExpressHandler = RequestHandler;
1300
+ type ExpressRouter = IRouter;
1301
+ interface ExpressAdapterOptions {
1302
+ basePath?: string;
1303
+ }
1304
+
1305
+ /**
1306
+ * Options for helmet middleware
1307
+ */
1308
+ interface HelmetOptions {
1309
+ dnsPrefetchControl?: boolean;
1310
+ frameguard?: boolean | {
1311
+ action: "DENY" | "SAMEORIGIN" | string;
1312
+ };
1313
+ hsts?: boolean | {
1314
+ maxAge?: number;
1315
+ includeSubDomains?: boolean;
1316
+ preload?: boolean;
1317
+ };
1318
+ contentTypeOptions?: boolean;
1319
+ ieNoOpen?: boolean;
1320
+ xssFilter?: boolean;
1321
+ referrerPolicy?: false | string;
1322
+ crossOriginResourcePolicy?: false | string;
1323
+ crossOriginOpenerPolicy?: false | string;
1324
+ crossOriginEmbedderPolicy?: false | string;
1325
+ contentSecurityPolicy?: false | string;
1326
+ }
1327
+
1328
+ interface JsonOptions {
1329
+ /**
1330
+ * The maximum size of the JSON body in bytes.
1331
+ * If the body is larger than this limit, the request will be rejected.
1332
+ * Default: 100kb
1333
+ */
1334
+ sizeLimit?: `${number}mb` | `${number}kb`;
1335
+ /**
1336
+ * If true, the JSON body will be parsed as an empty object if it is empty.
1337
+ * Default: false (body will be undefined)
1338
+ */
1339
+ parseEmptyBodyAsObject?: boolean;
1340
+ /**
1341
+ * The encoding to use when decoding the request body.
1342
+ * Default: "utf-8"
1343
+ */
1344
+ encoding?: TextDecoderEncoding;
1345
+ /**
1346
+ * The custom error message to return when the JSON body is too large.
1347
+ * Default: response with status 413 and body { message: "ERR_REQUEST_BODY_TOO_LARGE" }
1348
+ */
1349
+ customErrorMessage?: {
1350
+ status?: number;
1351
+ message?: string;
1352
+ };
1353
+ }
1354
+ /**
1355
+ * Supported text encodings for TextDecoder.
1356
+ * Based on the WHATWG Encoding Standard.
1357
+ */
1358
+ type TextDecoderEncoding = "utf-8" | "utf-16le" | "utf-16be" | "gbk" | "gb18030" | "big5" | "euc-jp" | "iso-2022-jp" | "shift-jis" | "euc-kr" | "iso-2022-kr" | "iso-8859-1" | "iso-8859-2" | "iso-8859-3" | "iso-8859-4" | "iso-8859-5" | "iso-8859-6" | "iso-8859-7" | "iso-8859-8" | "iso-8859-9" | "iso-8859-10" | "iso-8859-13" | "iso-8859-14" | "iso-8859-15" | "iso-8859-16" | "windows-1250" | "windows-1251" | "windows-1252" | "windows-1253" | "windows-1254" | "windows-1255" | "windows-1256" | "windows-1257" | "windows-1258" | "x-mac-cyrillic" | "x-mac-greek" | "x-mac-icelandic" | "x-mac-latin2" | "x-mac-roman" | "x-mac-turkish" | "koi8-r" | "koi8-u";
1359
+
1360
+ type LoggerOptions = Parameters<typeof pino$1>[0];
1361
+
1362
+ interface LogOptions {
1363
+ /**
1364
+ * Whether to log the request.
1365
+ * @default true
1366
+ */
1367
+ logRequest?: boolean;
1368
+ /**
1369
+ * What to log for the request.
1370
+ * @default true for all properties
1371
+ */
1372
+ requestPayload?: {
1373
+ method?: boolean;
1374
+ url?: boolean;
1375
+ ip?: boolean;
1376
+ headers?: boolean;
1377
+ /** Only json objects and strings are logged */
1378
+ body?: boolean;
1379
+ };
1380
+ /**
1381
+ * Whether to log the response.
1382
+ * @default true
1383
+ */
1384
+ logResponse?: boolean;
1385
+ /**
1386
+ * Whether to log the response body.
1387
+ * @default false
1388
+ */
1389
+ responsePayload?: {
1390
+ status?: boolean;
1391
+ headers?: boolean;
1392
+ body?: boolean;
1393
+ };
1394
+ /**
1395
+ * What to log for the response.
1396
+ * @default true for all properties
1397
+ */
1398
+ pinoOptions?: LoggerOptions;
1399
+ }
1400
+
1401
+ type MethodOverrideOptions = {
1402
+ /**
1403
+ * HTTP methods that can be overridden
1404
+ * Default: ['POST']
1405
+ */
1406
+ methods?: string[];
1407
+ /**
1408
+ * Header name to read the override method from
1409
+ * Default: 'X-HTTP-Method-Override'
1410
+ */
1411
+ header?: string;
1412
+ };
1413
+
1414
+ type StorageStrategy = "memory" | "custom";
1415
+ type BaseRateLimiterOptions = {
1416
+ /**
1417
+ * The number of requests per window
1418
+ * @default 100
1419
+ */
1420
+ limit?: number;
1421
+ /**
1422
+ * The message to return when the rate limit is exceeded
1423
+ * @default "ERR_RATE_LIMIT_EXCEEDED"
1424
+ */
1425
+ message?: string;
1426
+ /**
1427
+ * The status code to return when the rate limit is exceeded
1428
+ * @default 429
1429
+ */
1430
+ statusCode?: number;
1431
+ /**
1432
+ * The storage strategy to use
1433
+ * @default "memory"
1434
+ */
1435
+ storageStrategy?: StorageStrategy;
1436
+ };
1437
+ /**
1438
+ * Key Strategy
1439
+ */
1440
+ type IpRateLimiterOptions = {
1441
+ /**
1442
+ * The type of rate limiter
1443
+ */
1444
+ type: "ip";
1445
+ } & BaseRateLimiterOptions;
1446
+ type CustomRateLimiterOptions = {
1447
+ /**
1448
+ * The type of rate limiter
1449
+ */
1450
+ type: "custom";
1451
+ /**
1452
+ * Generate a key for the rate limiter from the request (e.g. user id, email, etc.)
1453
+ */
1454
+ key: (req: Request$1) => string;
1455
+ /**
1456
+ * The storage strategy to use
1457
+ * @default "memory"
1458
+ */
1459
+ storageStrategy?: StorageStrategy;
1460
+ } & BaseRateLimiterOptions;
1461
+ /**
1462
+ * Memory Storage Strategy
1463
+ */
1464
+ type MemoryStorageStrategy = {
1465
+ /**
1466
+ * The type of storage strategy
1467
+ */
1468
+ type: "memory";
1469
+ /**
1470
+ * The window in milliseconds
1471
+ * @default 60000
1472
+ */
1473
+ windowMs?: number;
1474
+ };
1475
+ /**
1476
+ * Custom Storage Strategy
1477
+ */
1478
+ type CustomStorageStrategy = {
1479
+ /**
1480
+ * The type of storage strategy
1481
+ */
1482
+ type: "custom";
1483
+ /**
1484
+ * Set a value in the storage
1485
+ */
1486
+ set: (key: string, value: any) => Promise<void>;
1487
+ /**
1488
+ * Get a value from the storage
1489
+ */
1490
+ get: (key: string) => Promise<any>;
1491
+ };
1492
+ type StorageOptions$1 = MemoryStorageStrategy | CustomStorageStrategy;
1493
+ /**
1494
+ * Rate limiter options
1495
+ */
1496
+ type RateLimiterKeyOptions = IpRateLimiterOptions | CustomRateLimiterOptions;
1497
+
1498
+ type SessionStore = {
1499
+ get: (sid: string) => Promise<Record<string, any> | undefined>;
1500
+ set: (sid: string, value: Record<string, any>, ttlSeconds?: number) => Promise<void>;
1501
+ destroy: (sid: string) => Promise<void>;
1502
+ };
1503
+ type SessionOptions = {
1504
+ /** Cookie name used for session id */
1505
+ name?: string;
1506
+ /** Secret used to sign session id (optional, for future) */
1507
+ secret?: string;
1508
+ /** TTL seconds for session */
1509
+ ttl?: number;
1510
+ /** Custom store, default is in-memory */
1511
+ store?: SessionStore;
1512
+ /** Whether to set HttpOnly secure flags */
1513
+ cookie?: {
1514
+ path?: string;
1515
+ httpOnly?: boolean;
1516
+ secure?: boolean;
1517
+ sameSite?: "Strict" | "Lax" | "None";
1518
+ domain?: string;
1519
+ };
1520
+ };
1521
+
1522
+ /**
1523
+ * Swagger plugin that serves the swagger UI and JSON specification, by default the UI will be available at /docs and the JSON specification at /docs/json
1524
+ * @warning The json specification is always available at /${globalOptions.path}/json
1525
+ * @internal
1526
+ */
1527
+ declare const swagger: (globalOptions?: SwaggerGlobalOptions | boolean) => void;
1528
+
1529
+ type TimeoutOptions = {
1530
+ /** Timeout in milliseconds */
1531
+ ms: number;
1532
+ };
1533
+
1534
+ type TrustProxyOptions = {
1535
+ /** Enable using X-Forwarded-* headers to determine client IP */
1536
+ trust?: boolean;
1537
+ /** Header name to read the client IP chain from */
1538
+ header?: string;
1539
+ /** Select which IP from the chain to use: 'first' (client) or 'last' (closest proxy) */
1540
+ hop?: "first" | "last";
1541
+ };
1542
+
1543
+ /**
1544
+ * Options for URL-encoded middleware
1545
+ */
1546
+ type UrlEncodedOptions = {
1547
+ /**
1548
+ * The maximum size of the URL-encoded body.
1549
+ * Supports formats like "5mb", "100kb".
1550
+ * Defaults to "1mb".
1551
+ */
1552
+ limit?: `${number}mb` | `${number}kb`;
1553
+ /**
1554
+ * Whether to parse extended syntax (objects and arrays). Defaults to false.
1555
+ */
1556
+ extended?: boolean;
1557
+ /**
1558
+ * The character encoding to use when parsing. Defaults to 'utf8'.
1559
+ */
1560
+ charset?: string;
1561
+ /**
1562
+ * Whether to allow empty values. Defaults to true.
1563
+ */
1564
+ allowEmpty?: boolean;
1565
+ /**
1566
+ * Maximum number of parameters to parse. Defaults to 1000.
1567
+ */
1568
+ parameterLimit?: number;
1569
+ };
1570
+
1571
+ /**
1572
+ * The next function.
1573
+ * This is the function that is passed to the handler function.
1574
+ * It has a pointer to the next middleware or handler function of the middleware chain.
1575
+ */
1576
+ type NextFunction = () => SyncOrAsync;
1577
+
1578
+ type ServerPlugin = {
1579
+ cors?: CorsOptions;
1580
+ json?: JsonOptions;
1581
+ static?: StaticPluginOptions;
1582
+ fileParser?: FilePluginOptions;
1583
+ helmet?: HelmetOptions;
1584
+ cookie?: CookieMiddlewareOptions;
1585
+ log?: LogOptions;
1586
+ urlencoded?: UrlEncodedOptions;
1587
+ rateLimiter?: {
1588
+ keyOptions?: RateLimiterKeyOptions;
1589
+ storageOptions?: StorageOptions$1;
1590
+ };
1591
+ trustProxy?: TrustProxyOptions;
1592
+ timeout?: TimeoutOptions;
1593
+ session?: SessionOptions;
1594
+ methodOverride?: MethodOverrideOptions;
1595
+ compression?: CompressionOptions;
1596
+ asyncLocalStorage?: AsyncLocalStorageContextSetters;
1597
+ };
1598
+ type NodeHttpClient = "http" | "http2" | "https" | "http2-secure";
1599
+ type ServerOptions<H extends NodeHttpClient = NodeHttpClient> = {
1600
+ /** Specific node client to use for nodejs, default to `http` */
1601
+ nodeHttpClient?: H;
1602
+ /** The port to listen on, uses the PORT env if present, defaults to 80 */
1603
+ port?: number;
1604
+ /** The hostname to listen on, uses the HOST env if present, defaults to 0.0.0.0 */
1605
+ host?: string;
1606
+ /** Controller patterns to match, defaults to an empty array */
1607
+ controllerPatterns?: string[];
1608
+ /** Basic plugins to apply to all requests, plugins are applied in order based on where they are defined in the `plugins` object, by default no plugins are applied */
1609
+ plugins?: ServerPlugin;
1610
+ /** The tap options to interact with the underlying server connector before it is used to listen for incoming requests */
1611
+ tapOptions?: ServerTapOptions;
1612
+ /** Whether to use the body parser plugin, by default it is true, it is really recommended to use it */
1613
+ useBodyParser?: boolean;
1614
+ /**
1615
+ * The swagger options to apply to the server, by default swagger plugin is applied with standard options, you can pass a boolean to enable or disable the plugin or you can pass an object to apply custom options to the plugin
1616
+ * @example
1617
+ * ```ts
1618
+ * const server = new Server({
1619
+ * swagger: true,
1620
+ * });
1621
+ * ```
1622
+ */
1623
+ swagger?: Parameters<typeof swagger>[0] | boolean;
1624
+ /**
1625
+ * The graphql options to apply to the server, by default graphql plugin is not enabled, you can pass a boolean to enable or disable the plugin or you can pass an object to apply custom options to the plugin (when options are provided the plugin is always enabled)
1626
+ * @example
1627
+ * ```ts
1628
+ * const server = new Server({
1629
+ * graphql: true,
1630
+ * });
1631
+ * ```
1632
+ * @example
1633
+ * ```ts
1634
+ * const server = new Server({
1635
+ * graphql: {
1636
+ * schema: createSchema({ typeDefs: `type Query { hello: String }`, resolvers: { Query: { hello: () => 'Hello World' } } }),
1637
+ * },
1638
+ * });
1639
+ * ```
1640
+ */
1641
+ graphql?: GraphQLOptions;
1642
+ /**
1643
+ * The ajv instance to use for the server for validation, by default a global instance is used, you can pass a custom instance to use for the server
1644
+ * @example
1645
+ * ```ts
1646
+ * const server = new Server({
1647
+ * ajvInstance: new Ajv(),
1648
+ * });
1649
+ * ```
1650
+ */
1651
+ ajvInstance?: Ajv;
1652
+ } & (H extends "https" | "http2-secure" ? HttpsOptions<H> : {});
1653
+ /** Internal resolved server options with all required properties */
1654
+ type ResolvedServerOptions = {
1655
+ nodeHttpClient: NodeHttpClient;
1656
+ port: number;
1657
+ host: string;
1658
+ controllerPatterns: string[];
1659
+ plugins: ServerPlugin;
1660
+ tapOptions: ServerTapOptions;
1661
+ useBodyParser: boolean;
1662
+ swagger: Parameters<typeof swagger>[0] | boolean;
1663
+ graphql?: GraphQLOptions;
1664
+ };
1665
+ type ServerErrorHandler = (req: Request$1, res: Response$1, next: NextFunction, error: Error) => SyncOrAsync;
1666
+ interface ServerInterface {
1667
+ /**
1668
+ * Whether the server is in production mode NODE_ENV is set to "production"
1669
+ */
1670
+ isProduction: boolean;
1671
+ /**
1672
+ * Whether the server is listening for requests
1673
+ */
1674
+ isListening: boolean;
1675
+ /**
1676
+ * The url of the server
1677
+ */
1678
+ url: string;
1679
+ /**
1680
+ * The port of the server
1681
+ */
1682
+ port: number;
1683
+ /**
1684
+ * The host of the server
1685
+ */
1686
+ host: string;
1687
+ /**
1688
+ * Settings applied before server is listening, this is used to tap into the server connector for the current runtime and modify it before it is used to listen for incoming requests
1689
+ * @warning Must be used before `listen` method
1690
+ */
1691
+ tapOptions?: ServerTapOptions;
1692
+ /**
1693
+ * Main singleton router instance of the server
1694
+ */
1695
+ router: ClientRouter;
1696
+ /**
1697
+ * Hash the given data using the native hash function of the current runtime
1698
+ * @param data - The data to hash
1699
+ * @returns The hashed data
1700
+ */
1701
+ hash: (data: string) => Promise<string>;
1702
+ /**
1703
+ * Compare the given data with the given hash using the native hash function of the current runtime
1704
+ * @param hash - The hash to compare the data with
1705
+ * @param data - The data to compare with the hash
1706
+ * @returns Whether the data matches the hash
1707
+ */
1708
+ compareHash: (hash: string, data: string) => Promise<boolean>;
1709
+ /**
1710
+ * Get the environment variables of the server using the native environment variables of the current runtime
1711
+ */
1712
+ getEnvironment: () => Record<string, string>;
1713
+ /**
1714
+ * The path to the temporary directory, you can append a path to the temporary directory to get a new path.
1715
+ * It uses the current working directory of the runtime to get the base path.
1716
+ * @example
1717
+ * ```ts
1718
+ * server.tmpPath("my-app"); // -> ${cwd}/tmp/my-app
1719
+ * ```
1720
+ */
1721
+ tmpDir: (...append: string[]) => string;
1722
+ /**
1723
+ * Create a new directory
1724
+ * @param path - The path to the directory
1725
+ * @param options - The options to create the directory
1726
+ * @param options.recursive - Whether to create the directory recursively
1727
+ * @param options.mode - The mode of the directory
1728
+ */
1729
+ mkdir: (path: string, options?: {
1730
+ recursive?: boolean;
1731
+ mode?: number | string;
1732
+ }) => Promise<void>;
1733
+ /**
1734
+ * Mount an Express middleware or router at a specific path for compatibility with Express-based libraries like AdminJS
1735
+ * @param pathOrMiddleware - The path to mount at, or the Express middleware/router if mounting at root
1736
+ * @param maybeMiddleware - The Express middleware or router when path is provided
1737
+ */
1738
+ useExpress: (pathOrMiddleware: string | RequestHandler | ExpressRouter, maybeMiddleware?: RequestHandler | ExpressRouter) => void;
1739
+ /**
1740
+ * Convert an Express middleware to a Balda-compatible middleware
1741
+ * @param middleware - The Express middleware to convert
1742
+ * @returns A Balda-compatible middleware
1743
+ */
1744
+ expressMiddleware: (middleware: RequestHandler) => ServerRouteMiddleware;
1745
+ /**
1746
+ * Mount an Express router at a specific base path
1747
+ * @param basePath - The base path to mount the router at
1748
+ * @param expressRouter - The Express router to mount
1749
+ */
1750
+ mountExpressRouter: (basePath: string, expressRouter: ExpressRouter) => void;
1751
+ /**
1752
+ * Shorthand for the server.router.get method
1753
+ */
1754
+ get: (...args: any[]) => void;
1755
+ /**
1756
+ * Shorthand for the server.router.post method
1757
+ */
1758
+ post: (...args: any[]) => void;
1759
+ /**
1760
+ * Shorthand for the server.router.put method
1761
+ */
1762
+ put: (...args: any[]) => void;
1763
+ /**
1764
+ * Shorthand for the server.router.patch method
1765
+ */
1766
+ patch: (...args: any[]) => void;
1767
+ /**
1768
+ * Shorthand for the server.router.delete method
1769
+ */
1770
+ delete: (...args: any[]) => void;
1771
+ /**
1772
+ * Shorthand for the server.router.options method
1773
+ */
1774
+ options: (...args: any[]) => void;
1775
+ /**
1776
+ * Shorthand for the server.router.head method
1777
+ */
1778
+ head: (...args: any[]) => void;
1779
+ /**
1780
+ * Shorthand for the server.router.group method
1781
+ */
1782
+ group: (...args: any[]) => void;
1783
+ /**
1784
+ * Get the node server instance, you must be using node runtime to use this method based on the nodeHttpClient option passed to the server constructor (defaults to http)
1785
+ * @throws if the runtime is not node
1786
+ */
1787
+ getNodeServer: () => RuntimeServerMap<"node", NodeHttpClient>;
1788
+ /**
1789
+ * Get the bun server instance, you must be using bun runtime to use this method
1790
+ * @throws if the runtime is not bun
1791
+ */
1792
+ getBunServer: () => RuntimeServerMap<"bun">;
1793
+ /**
1794
+ * Get the deno server instance, you must be using deno runtime to use this method
1795
+ * @throws if the runtime is not deno
1796
+ */
1797
+ getDenoServer: () => RuntimeServerMap<"deno">;
1798
+ /**
1799
+ * Embed the given key into the server instance, this is useful for embedding the server with custom context inside the server instance, you can extend the server with your own properties to type it
1800
+ * @param key - The key to embed
1801
+ * @param value - The value to embed
1802
+ * @warning There are some keys that are protected and cannot be embedded, you can find the list of protected keys in the PROTECTED_KEYS constant
1803
+ * @throws An error if the key is already defined in the server instance or if the key is protected
1804
+ * @example
1805
+ * ```typescript
1806
+ * // For better type safety, you can declare a module for the server interface
1807
+ * declare module "balda" {
1808
+ * interface Server {
1809
+ * myCustomProperty: string;
1810
+ * }
1811
+ * }
1812
+ *
1813
+ * server.embed("myCustomProperty", "myCustomValue");
1814
+ * console.log(server.myCustomProperty); // Type safe if ServerInterface is extended
1815
+ * ```
1816
+ */
1817
+ embed: (key: string, value: any) => void;
1818
+ /**
1819
+ * Register a signal event listener to the server, this is useful for handling signals like SIGINT, SIGTERM, etc.
1820
+ * @param event - The signal event to listen for
1821
+ * @param cb - The callback to be called when the signal event is received
1822
+ */
1823
+ on: (event: SignalEvent, cb: () => SyncOrAsync) => void;
1824
+ /**
1825
+ * Register a signal event listener to the server, this is useful for handling signals like SIGINT, SIGTERM, etc.
1826
+ * @param event - The signal event to listen for
1827
+ * @param cb - The callback to be called when the signal event is received
1828
+ */
1829
+ once: (event: SignalEvent, cb: () => SyncOrAsync) => void;
1830
+ /**
1831
+ * Register a global middleware to be applied to all routes after the listener is bound, the middleware is applied in the order it is registered
1832
+ */
1833
+ use: (middleware: ServerRouteMiddleware) => void;
1834
+ /**
1835
+ * Set the error handler for the server
1836
+ * @param errorHandler - The error handler to be applied to all routes
1837
+ */
1838
+ setErrorHandler: (errorHandler?: ServerErrorHandler) => void;
1839
+ /**
1840
+ * Set the not found handler for the server
1841
+ * @param notFoundHandler - The not found handler to be applied to all routes
1842
+ */
1843
+ setNotFoundHandler: (notFoundHandler?: ServerRouteHandler) => void;
1844
+ /**
1845
+ * Binds the server to the port and hostname defined in the serverOptions, meant to be called only once
1846
+ * @warning All routes defined with decorators are defined on this method just before the server starts listening for requests
1847
+ */
1848
+ listen: (cb?: ServerListenCallback) => void;
1849
+ /**
1850
+ * Closes the server and frees the port
1851
+ */
1852
+ close: () => Promise<void>;
1853
+ /**
1854
+ * Get a mock server instance, useful for testing purposes
1855
+ */
1856
+ getMockServer: () => Promise<MockServer>;
1857
+ /**
1858
+ * Exit current runtime process with the given code based on the current runtime
1859
+ * @param code - The code to exit with, defaults to 0
1860
+ * @example
1861
+ * ```typescript
1862
+ * server.exit(1); // If node process.exit(1) is called
1863
+ * server.exit(); // If deno Deno.exit(0) is called
1864
+ * ```
1865
+ */
1866
+ exit: (code?: number) => void;
1867
+ }
1868
+ type StandardMethodOptions = {
1869
+ middlewares?: ServerRouteMiddleware[] | ServerRouteMiddleware;
1870
+ swagger?: SwaggerRouteOptions;
1871
+ };
1872
+ type SignalEvent = Deno.Signal | NodeJS.Signals;
1873
+
1874
+ type RunTimeType = "bun" | "node" | "deno";
1875
+
1876
+ type HttpMethod = "GET" | "POST" | "PUT" | "DELETE" | "PATCH" | "OPTIONS" | "HEAD";
1877
+ type NodeServer = Server$2 | Server$1 | Http2Server;
1878
+ type RuntimeServer = NodeServer | ReturnType<typeof Bun.serve> | ReturnType<typeof Deno.serve>;
1879
+ type RuntimeServerMap<T extends RunTimeType, H extends NodeHttpClient = "http"> = T extends "node" ? H extends "https" ? Server$1 : H extends "http2" | "http2-secure" ? Http2Server : Server$2 : T extends "bun" ? ReturnType<typeof Bun.serve> : T extends "deno" ? ReturnType<typeof Deno.serve> : never;
1880
+ type HttpsOptions<T extends NodeHttpClient> = T extends "https" | "http2-secure" ? {
1881
+ /** HTTPS/TLS options, required when nodeHttpClient is 'https' or 'http2-secure' */
1882
+ httpsOptions: ServerOptions$1;
1883
+ } : never;
1884
+ type ServerConnectInput<H extends NodeHttpClient = NodeHttpClient> = {
1885
+ /** The port to listen on, defaults to 80 */
1886
+ port: number;
1887
+ /** The hostname to listen on, defaults to 0.0.0.0 */
1888
+ host: string;
1889
+ /** The server routes with their corresponding handler */
1890
+ routes: ServerRoute[];
1891
+ /** The options for the server tap function */
1892
+ tapOptions?: ServerTapOptions;
1893
+ /** The runtime to use for the server */
1894
+ runtime: RunTimeType;
1895
+ /** Specific node client to use */
1896
+ nodeHttpClient: H;
1897
+ /** The graphql options to apply to the server */
1898
+ graphql?: GraphQL;
1899
+ } & (H extends "https" ? HttpsOptions<H> : {});
1900
+ type ServerRouteMiddleware = (req: Request$1, res: Response$1, next: NextFunction) => SyncOrAsync;
1901
+ type ServerRouteHandler = (req: Request$1, res: Response$1) => SyncOrAsync;
1902
+ interface ServerRoute {
1903
+ /** The path for the route */
1904
+ path: string;
1905
+ /** The HTTP method for the route */
1906
+ method: HttpMethod;
1907
+ /** The handler to call when the route is requested */
1908
+ handler: ServerRouteHandler;
1909
+ /** The middleware chain to call before the handler */
1910
+ middlewares?: ServerRouteMiddleware[];
1911
+ }
1912
+ type ServerListenCallback = ({ port, host, url, }: {
1913
+ port: number;
1914
+ host: string;
1915
+ url: string;
1916
+ }) => SyncOrAsync;
1917
+ /**
1918
+ * Custom bun fetch call to be used as an hook inside Bun.serve method
1919
+ */
1920
+ type CustomBunFetch = (req: Request$1, server: Bun.Server<any>) => SyncOrAsync;
1921
+ /**
1922
+ * Custom deno fetch call to be used as an hook inside Deno.serve method
1923
+ */
1924
+ type CustomDenoFetch = (...options: Parameters<Parameters<typeof Deno.serve>[0]["handler"]>) => SyncOrAsync<Response | void>;
1925
+ /**
1926
+ * The options for the server tap function, allows you to interact with the server behavior before it is used to listen for incoming requests
1927
+ */
1928
+ type ServerTapOptionsBuilder<T extends RunTimeType> = T extends "node" ? (req: Omit<IncomingMessage, "url">) => Promise<void> : T extends "bun" ? Partial<Parameters<typeof Bun.serve>[0]> & {
1929
+ fetch?: CustomBunFetch;
1930
+ } : T extends "deno" ? Partial<Omit<Parameters<typeof Deno.serve>[0], "handler">> & {
1931
+ handler?: CustomDenoFetch;
1932
+ websocket?: {
1933
+ open?: (ws: WebSocket) => void;
1934
+ message?: (ws: WebSocket, message: string) => void;
1935
+ close?: (ws: WebSocket) => void;
1936
+ };
1937
+ } : never;
1938
+ type BunTapOptions = ServerTapOptionsBuilder<"bun">;
1939
+ type NodeTapOptions = ServerTapOptionsBuilder<"node">;
1940
+ type DenoTapOptions = ServerTapOptionsBuilder<"deno">;
1941
+ type ServerTapOptions = {
1942
+ bun?: BunTapOptions;
1943
+ node?: NodeTapOptions;
1944
+ deno?: DenoTapOptions;
1945
+ };
1946
+
1947
+ /**
1948
+ * Decorator to mark a middleware for a route or a controller class
1949
+ */
1950
+ declare const middleware: (middleware: ServerRouteMiddleware | ServerRouteMiddleware[]) => (target: any, propertyKey?: string, descriptor?: PropertyDescriptor) => any;
1951
+
1952
+ interface SerializeOptions {
1953
+ /**
1954
+ * The status code to serialize the response body against (useful only for the documentation does not affect the actual response status)
1955
+ * @default 200
1956
+ */
1957
+ status?: number;
1958
+ /**
1959
+ * Whether to use safe serialization (returns original data if serialization fails instead of throwing)
1960
+ * Advised to only set unsafe if development environment
1961
+ * @default true
1962
+ */
1963
+ safe?: boolean;
1964
+ }
1965
+
1966
+ declare const serialize: <T extends ZodType | AjvCompileParams[0]>(schema: T, options?: SerializeOptions) => (target: any, propertyKey: string, descriptor: PropertyDescriptor) => void;
1967
+
1968
+ interface CustomValidationError {
1969
+ status?: number;
1970
+ message?: string;
1971
+ }
1972
+ interface ValidationOptions {
1973
+ /**
1974
+ * The schema to validate the request body against (Zod schema or OpenAPI schema)
1975
+ */
1976
+ body?: ZodType | AjvCompileParams[0];
1977
+ /**
1978
+ * The schema to validate the query parameters against (Zod schema or OpenAPI schema)
1979
+ */
1980
+ query?: ZodType | AjvCompileParams[0];
1981
+ /**
1982
+ * The schema to validate both body and query against (Zod schema or OpenAPI schema)
1983
+ */
1984
+ all?: ZodType | AjvCompileParams[0];
1985
+ /**
1986
+ * Whether to use safe validation (returns original data if validation fails instead of throwing)
1987
+ * @default false
1988
+ */
1989
+ safe?: boolean;
1990
+ }
1991
+
1992
+ declare const validate: {
1993
+ (options: ValidationOptions & {
1994
+ customError?: CustomValidationError;
1995
+ }): (target: any, propertyKey: string, descriptor: PropertyDescriptor) => PropertyDescriptor;
1996
+ query(schema: ZodType | AjvCompileParams[0], customError?: CustomValidationError): (target: any, propertyKey: string, descriptor: PropertyDescriptor) => PropertyDescriptor;
1997
+ body(schema: ZodType | AjvCompileParams[0], customError?: CustomValidationError): (target: any, propertyKey: string, descriptor: PropertyDescriptor) => PropertyDescriptor;
1998
+ all(schema: ZodType | AjvCompileParams[0], customError?: CustomValidationError): (target: any, propertyKey: string, descriptor: PropertyDescriptor) => PropertyDescriptor;
1999
+ };
2000
+
2001
+ /**
2002
+ * Base class for cron jobs with logger instance
2003
+ * @example
2004
+ * export default class MyCron extends BaseCron {
2005
+ * @cron("* * * * *")
2006
+ * handle() {
2007
+ * this.logger.info("Running cron job");
2008
+ * }
2009
+ * }
2010
+ */
2011
+ declare class BaseCron {
2012
+ protected readonly logger: pino.Logger<string, boolean>;
2013
+ }
2014
+
2015
+ declare class CronService {
2016
+ static scheduledJobs: CronSchedule[];
2017
+ /**
2018
+ * @description Schedule a cron job.
2019
+ * @internal
2020
+ * @example
2021
+ * CronService.register('test', '0 0 * * *', () => {
2022
+ * console.log('test');
2023
+ * }, {
2024
+ * timezone: 'Europe/Istanbul',
2025
+ * });
2026
+ */
2027
+ static register(name: string, ...args: CronScheduleParams): void;
2028
+ /**
2029
+ * @description Start the cron scheduler.
2030
+ */
2031
+ static run(): Promise<void>;
2032
+ /**
2033
+ * @description Main error handler for cron jobs. You can write your own error handler by overriding this static method for example with sentry.
2034
+ */
2035
+ static globalErrorHandler(context: TaskContext): void;
2036
+ /**
2037
+ * @description Import all cron jobs from the app/cron/schedules directory
2038
+ */
2039
+ static massiveImportCronJobs(cronJobPatterns: string[]): Promise<void>;
2040
+ }
2041
+ declare const setCronGlobalErrorHandler: (globalErrorHandler: (...args: Parameters<(typeof CronService)["globalErrorHandler"]>) => void) => void;
2042
+
2043
+ declare class BullMQPubSub implements PubSub<"bullmq"> {
2044
+ private queues;
2045
+ private workers;
2046
+ private bullmqClient;
2047
+ publish<T extends QueueTopicKey>(topic: T, payload: QueueTopic[T], options?: PublishOptions<"bullmq">): Promise<{
2048
+ id: string;
2049
+ }>;
2050
+ subscribe<T extends QueueTopicKey>(topic: T, handler: (payload: QueueTopic[T]) => Promise<void>): Promise<void>;
2051
+ private getQueue;
2052
+ private getBullMQClient;
2053
+ }
2054
+
2055
+ declare class PGBossPubSub implements PubSub<"pgboss"> {
2056
+ private boss;
2057
+ private createdQueues;
2058
+ publish<T extends QueueTopicKey>(topic: T, payload: QueueTopic[T], options?: PublishOptions<"pgboss">): Promise<{
2059
+ id: string;
2060
+ }>;
2061
+ subscribe<T extends QueueTopicKey>(topic: T, handler: (payload: QueueTopic[T]) => Promise<void>): Promise<void>;
2062
+ private getBoss;
2063
+ private ensureQueue;
2064
+ }
2065
+
2066
+ declare class SQSPubSub implements PubSub<"sqs"> {
2067
+ private consumers;
2068
+ private client?;
2069
+ private sqsLib;
2070
+ private sqsConsumerLib;
2071
+ publish<T extends QueueTopicKey>(topic: T, payload: QueueTopic[T], options?: PublishOptions<"sqs">): Promise<{
2072
+ id: string;
2073
+ }>;
2074
+ subscribe<T extends QueueTopicKey>(topic: T, handler: (payload: QueueTopic[T]) => Promise<void>): Promise<void>;
2075
+ private getClient;
2076
+ private getSqsLib;
2077
+ private getSqsConsumerLib;
2078
+ private resolveQueueUrl;
2079
+ }
2080
+
2081
+ type BullMQAddTaskOptions = Parameters<Queue["add"]>[2];
2082
+ type PGBossSendOptions = Parameters<PgBoss["send"]>[2];
2083
+ type SQSPublishOptions = Parameters<SQSClient["send"]>[0];
2084
+ type PublishOptions<T extends QueueProviderKey> = T extends "bullmq" ? BullMQAddTaskOptions : T extends "sqs" ? SQSPublishOptions : T extends "pgboss" ? PGBossSendOptions : never;
2085
+ interface QueueTopic {
2086
+ }
2087
+ type QueueTopicKey = keyof QueueTopic;
2088
+ interface PubSub<P extends QueueProviderKey = any> {
2089
+ publish: <T extends QueueTopicKey>(topic: T, payload: QueueTopic[T], options: PublishOptions<P>) => Promise<{
2090
+ id: string;
2091
+ }>;
2092
+ subscribe: <T extends QueueTopicKey>(topic: T, handler: (payload: QueueTopic[T]) => Promise<void>) => Promise<void>;
2093
+ }
2094
+ interface QueueProvider {
2095
+ bullmq: BullMQPubSub;
2096
+ sqs: SQSPubSub;
2097
+ pgboss: PGBossPubSub;
2098
+ }
2099
+ type QueueProviderKey = keyof QueueProvider;
2100
+
2101
+ /**
2102
+ * Decorator to register a queue handler
2103
+ * @param provider - The provider to use
2104
+ * @param topic - The topic to subscribe to
2105
+ * @returns A function to decorate the handler
2106
+ */
2107
+ declare const queue: {
2108
+ <P extends QueueProviderKey, T extends QueueTopicKey>(provider: P, topic: T): (target: any, propertyKey: string, descriptor: PropertyDescriptor) => PropertyDescriptor;
2109
+ bullmq<T extends QueueTopicKey>(topic: T): (target: any, propertyKey: string, descriptor: PropertyDescriptor) => PropertyDescriptor;
2110
+ sqs<T extends QueueTopicKey>(topic: T): (target: any, propertyKey: string, descriptor: PropertyDescriptor) => PropertyDescriptor;
2111
+ pgboss<T extends QueueTopicKey>(topic: T): (target: any, propertyKey: string, descriptor: PropertyDescriptor) => PropertyDescriptor;
2112
+ };
2113
+
2114
+ type QueueRegistration = {
2115
+ name: string;
2116
+ topic: QueueTopicKey;
2117
+ handler: (payload: any) => Promise<void>;
2118
+ provider: QueueProviderKey;
2119
+ };
2120
+ declare class QueueService {
2121
+ static scheduledSubscribers: QueueRegistration[];
2122
+ static register(name: string, topic: QueueRegistration["topic"], handler: QueueRegistration["handler"], options?: {
2123
+ provider?: QueueProviderKey;
2124
+ }): void;
2125
+ static run(): Promise<void>;
2126
+ static massiveImportQueues(queueHandlerPatterns: string[]): Promise<void>;
2127
+ }
2128
+
2129
+ /**
2130
+ * Base class for MQTT handlers with logger instance
2131
+ * @example
2132
+ * declare module "balda" {
2133
+ * export interface BaseMqtt {
2134
+ * logger: Logger;
2135
+ * }
2136
+ * }
2137
+ *
2138
+ * export default class TemperatureHandler extends BaseMqtt {
2139
+ * @mqtt("home/temperature")
2140
+ * handle(topic: string, message: Buffer) {
2141
+ * this.logger.info("Received temperature:", message.toString());
2142
+ * }
2143
+ * }
2144
+ */
2145
+ declare class BaseMqtt {
2146
+ protected readonly logger: pino.Logger<string, boolean>;
2147
+ }
2148
+
2149
+ interface MqttTopics {
2150
+ }
2151
+ type MqttHandler<T extends MqttTopics> = (topic: keyof T, message: T[keyof T]) => void | Promise<void>;
2152
+ type MqttSubscription<T extends MqttTopics> = {
2153
+ name: string;
2154
+ topic: keyof T;
2155
+ handler: MqttHandler<T>;
2156
+ options?: IClientSubscribeOptions;
2157
+ };
2158
+ type MqttSubscribeOptions = IClientSubscribeOptions;
2159
+ type MqttPublishOptions = IClientPublishOptions;
2160
+ type MqttConnectionOptions = IClientOptions;
2161
+
2162
+ declare class MqttService {
2163
+ static subscriptions: MqttSubscription<MqttTopics>[];
2164
+ static client: MqttClient | null;
2165
+ static connectionOptions: MqttConnectionOptions;
2166
+ /**
2167
+ * @description Register an MQTT subscription handler.
2168
+ * @internal
2169
+ * @example
2170
+ * MqttService.register('test', 'home/temperature', (topic, message) => {
2171
+ * console.log('Received message:', message.toString());
2172
+ * }, { qos: 1 });
2173
+ */
2174
+ static register<T extends MqttTopics>(name: string, topic: keyof T, handler: MqttHandler<T>, options?: IClientSubscribeOptions): void;
2175
+ /**
2176
+ * @description Connect to the MQTT broker and subscribe to all registered topics.
2177
+ */
2178
+ static connect(connectionOptions?: MqttConnectionOptions): Promise<void>;
2179
+ /**
2180
+ * @description Subscribe to all registered topics.
2181
+ * @internal
2182
+ */
2183
+ private static subscribeToTopics;
2184
+ /**
2185
+ * @description Handle incoming MQTT messages.
2186
+ * @internal
2187
+ */
2188
+ private static handleMessage;
2189
+ /**
2190
+ * @description Main error handler for MQTT operations. You can write your own error handler by overriding this static method for example with sentry.
2191
+ */
2192
+ static globalErrorHandler(error: Error): SyncOrAsync<void>;
2193
+ static setOnDisconnectHandler(handler: () => void): void;
2194
+ static setOnReconnectHandler(handler: () => void): void;
2195
+ /**
2196
+ * @description Import all MQTT handlers from specified patterns
2197
+ */
2198
+ static massiveImportMqttHandlers(mqttHandlerPatterns: string[]): Promise<void>;
2199
+ /**
2200
+ * Create a decorator to subscribe to an MQTT topic
2201
+ * Messages are automatically parsed: Buffer -> JSON object (if valid) -> string
2202
+ * Supports MQTT wildcards: + (single level) and # (multi level)
2203
+ *
2204
+ * Handler signature can be either:
2205
+ * - `handler(message: T)` - just the message (topic omitted)
2206
+ * - `handler(topic: string, message: T)` - include topic for wildcards or logging
2207
+ *
2208
+ * @example
2209
+ * @mqtt.handler('home/temperature', { qos: 1 })
2210
+ * handleTemperature(message: { value: number; unit: string }) {
2211
+ * console.log('Temperature:', message.value, message.unit);
2212
+ * }
2213
+ *
2214
+ * @example With topic parameter (useful for wildcards)
2215
+ * @mqtt.handler('home/+/temperature', { qos: 1 })
2216
+ * handleRoomTemperature(topic: string, message: string) {
2217
+ * const room = topic.split('/')[1];
2218
+ * console.log(`${room} temperature:`, message);
2219
+ * }
2220
+ */
2221
+ subscribe<T extends MqttTopics = MqttTopics>(topic: keyof T, options?: IClientSubscribeOptions): (target: any, propertyKey: string, descriptor: PropertyDescriptor) => PropertyDescriptor;
2222
+ /**
2223
+ * @description Publish a message to an MQTT topic
2224
+ * @param topic - The topic to publish to
2225
+ * @param message - The message payload (string, Buffer, or object that will be JSON stringified)
2226
+ * @param options - Publish options (qos, retain, etc.)
2227
+ * @throws BaldaError if the MQTT client is not connected or is not installed as a dependency
2228
+ */
2229
+ publish<T extends MqttTopics>(topic: keyof T, message: T[keyof T], options?: MqttPublishOptions): Promise<void>;
2230
+ /**
2231
+ * @description Disconnect the MQTT client gracefully
2232
+ */
2233
+ static disconnect(): Promise<void>;
2234
+ }
2235
+ declare const setMqttGlobalErrorHandler: (globalErrorHandler: (...args: Parameters<(typeof MqttService)["globalErrorHandler"]>) => void) => void;
2236
+ /**
2237
+ * Singleton instance for publishing MQTT messages
2238
+ * @example
2239
+ * import { mqtt } from 'balda';
2240
+ *
2241
+ * await mqtt.publish('home/temperature', { value: 23.5, unit: 'C' }, { qos: 1 });
2242
+ */
2243
+ declare const mqtt: MqttService;
2244
+
2245
+ /**
2246
+ * Base class for queue handlers with logger instance
2247
+ * @example
2248
+ * export default class MyQueue extends BaseQueue {
2249
+ * @queue("bullmq", "my-topic")
2250
+ * async handle(payload: MyPayload) {
2251
+ * this.logger.info({ payload }, "Processing queue message");
2252
+ * }
2253
+ * }
2254
+ */
2255
+ declare class BaseQueue {
2256
+ protected readonly logger: pino.Logger<string, boolean>;
2257
+ }
2258
+
2259
+ /**
2260
+ * Options for BullMQ configuration
2261
+ * @param options - The options for BullMQ
2262
+ * @param errorHandler - Custom error handler that will be triggered when a job fails, for logging or debug purposes
2263
+ */
2264
+ type BullMQConfigurationOptions = ConstructorParameters<typeof Queue>[1] & {
2265
+ errorHandler?: (job: Job, error: Error) => SyncOrAsync;
2266
+ };
2267
+ declare class BullMQConfiguration {
2268
+ static options: BullMQConfigurationOptions;
2269
+ }
2270
+ /**
2271
+ * Define globally custom BullMQ configuration
2272
+ * @param options - The BullMQ configuration options
2273
+ */
2274
+ declare const defineBullMQConfiguration: (options: BullMQConfigurationOptions) => void;
2275
+
2276
+ type CustomQueueConfiguration = PubSub;
2277
+
2278
+ type PGBossConfigurationOptions = {
2279
+ connectionString?: string;
2280
+ boss?: unknown;
2281
+ errorHandler?: (error: Error) => SyncOrAsync;
2282
+ };
2283
+ declare class PGBossConfiguration {
2284
+ static options: PGBossConfigurationOptions;
2285
+ }
2286
+ declare const definePGBossConfiguration: (options: PGBossConfigurationOptions) => void;
2287
+
2288
+ type SQSConfigurationOptions = {
2289
+ client?: SQSClientConfig;
2290
+ consumer?: {
2291
+ batchSize?: number;
2292
+ visibilityTimeout?: number;
2293
+ waitTimeSeconds?: number;
2294
+ queueUrlMap: Record<QueueTopicKey, string>;
2295
+ };
2296
+ errorHandler?: (error: Error) => SyncOrAsync;
2297
+ };
2298
+ declare class SQSConfiguration {
2299
+ static options: SQSConfigurationOptions;
2300
+ }
2301
+ declare const defineSQSConfiguration: (options: SQSConfigurationOptions) => void;
2302
+
2303
+ /**
2304
+ * Main publisher for balda queue, has shortcuts for base providers, e.g. `publish.bullmq`
2305
+ * @param provider - The provider to use
2306
+ * @param topic - The topic to publish to
2307
+ * @param payload - The payload to publish
2308
+ * @param options - The options to use
2309
+ * @returns The id of the published job
2310
+ */
2311
+ declare const publish: {
2312
+ <P extends QueueProviderKey, T extends QueueTopicKey>(provider: P, topic: T, payload: QueueTopic[T], options?: PublishOptions<P>): Promise<{
2313
+ id: string;
2314
+ }>;
2315
+ bullmq<T extends QueueTopicKey>(topic: T, payload: QueueTopic[T], options?: PublishOptions<"bullmq">): Promise<{
2316
+ id: string;
2317
+ }>;
2318
+ sqs<T extends QueueTopicKey>(topic: T, payload: QueueTopic[T], options?: PublishOptions<"sqs">): Promise<{
2319
+ id: string;
2320
+ }>;
2321
+ pgboss<T extends QueueTopicKey>(topic: T, payload: QueueTopic[T], options?: PublishOptions<"pgboss">): Promise<{
2322
+ id: string;
2323
+ }>;
2324
+ };
2325
+
2326
+ declare class QueueManager {
2327
+ static map: Map<QueueProviderKey, PubSub>;
2328
+ static getProvider<P extends QueueProviderKey>(provider: P): PubSub<P>;
2329
+ static setProvider(provider: QueueProviderKey, pubsub: PubSub<QueueProviderKey>): void;
2330
+ }
2331
+
2332
+ /**
2333
+ * Main entry point to define the queue configuration, meant to be called only once in the application bootstrap
2334
+ * @bullmq - The BullMQ configuration options
2335
+ * @pgboss - The PGBoss configuration options
2336
+ * @sqs - The SQS configuration options
2337
+ * @string - The custom queue provider name with it's PubSub implementation
2338
+ * @example
2339
+ * defineQueueConfiguration({
2340
+ * bullmq: {
2341
+ * connection: {
2342
+ * host: "127.0.0.1",
2343
+ * password: "root",
2344
+ * username: "default",
2345
+ * db: 0,
2346
+ * },
2347
+ * },
2348
+ * pgboss: {
2349
+ * connectionString: "postgres://root:root@localhost:5432/database",
2350
+ * },
2351
+ * sqs: {
2352
+ * client: { region: "us-east-1" },
2353
+ * },
2354
+ * custom: new CustomPubSub(),
2355
+ * });
2356
+ * @example
2357
+ * defineQueueConfiguration({
2358
+ * custom: new CustomPubSub(),
2359
+ * });
2360
+ */
2361
+ declare const defineQueueConfiguration: (options: {
2362
+ bullmq?: Parameters<typeof defineBullMQConfiguration>[0];
2363
+ pgboss?: Parameters<typeof definePGBossConfiguration>[0];
2364
+ sqs?: Parameters<typeof defineSQSConfiguration>[0];
2365
+ } & { [key in Exclude<QueueProviderKey, "bullmq" | "pgboss" | "sqs">]?: CustomQueueConfiguration; }) => void;
2366
+
2367
+ /**
2368
+ * The logger instance, can be overridden by the `defineLoggerConfig` function
2369
+ */
2370
+ declare let logger: pino__default.Logger<string, boolean>;
2371
+ /**
2372
+ * Define the logger config, this will override the logger instance with the given options
2373
+ * @param options - The logger options
2374
+ */
2375
+ declare const defineLoggerConfig: (options?: LoggerOptions) => void;
2376
+
2377
+ type Argument = string;
2378
+ type FlagSchema = Record<string, string | number | boolean | Array<string | number | boolean>>;
2379
+
2380
+ type CommandOptions = {
2381
+ /**
2382
+ * If true, the command won't be killed after it's finished. Defaults to false.
2383
+ */
2384
+ keepAlive?: boolean;
2385
+ /**
2386
+ * Category for grouping commands in help output
2387
+ * @example 'generator', 'development', 'production', 'database'
2388
+ */
2389
+ category?: string;
2390
+ /**
2391
+ * Mark command as deprecated with optional replacement
2392
+ * @example { message: 'Use generate-controller instead', replacement: 'generate-controller' }
2393
+ */
2394
+ deprecated?: {
2395
+ message?: string;
2396
+ replacement?: string;
2397
+ };
2398
+ /**
2399
+ * Custom validation function that runs before handle()
2400
+ */
2401
+ validate?: (command: typeof Command) => boolean | Promise<boolean>;
2402
+ };
2403
+
2404
+ /**
2405
+ * Base class for all cli commands.
2406
+ * @abstract
2407
+ */
2408
+ declare abstract class Command {
2409
+ /**
2410
+ * The name of the command.
2411
+ */
2412
+ static commandName: string;
2413
+ /**
2414
+ * package manager that called the command (e.g. npx, yarn, bun etc.)
2415
+ */
2416
+ static calledBy: string;
2417
+ /**
2418
+ * The description of the command.
2419
+ */
2420
+ static description: string;
2421
+ /**
2422
+ * The help text of the command.
2423
+ */
2424
+ static help: string[] | string;
2425
+ /**
2426
+ * The options of the command.
2427
+ */
2428
+ static options: CommandOptions;
2429
+ /**
2430
+ * Static arguments in order to be validated by decorators. Will be fetched in the command instance.
2431
+ */
2432
+ static args: Argument[];
2433
+ /**
2434
+ * Static flags in order to be validated by decorators. Will be fetched in the command instance.
2435
+ */
2436
+ static flags: FlagSchema;
2437
+ static readonly logger: pino.Logger<string, boolean>;
2438
+ /**
2439
+ * Main entry point for the command.
2440
+ */
2441
+ static handle(): Promise<void>;
2442
+ /**
2443
+ * Enhanced help flag handler with rich formatting and command information
2444
+ */
2445
+ static handleHelpFlag(flags: FlagSchema): void;
2446
+ private static readonly generateHelpOutput;
2447
+ static readonly validateContext: (target: any) => void;
2448
+ }
2449
+
2450
+ declare class BuildCommand extends Command {
2451
+ static commandName: string;
2452
+ static description: string;
2453
+ static help: string[];
2454
+ static clearDist: boolean;
2455
+ static entry: string;
2456
+ static output: string;
2457
+ static tsconfig: string;
2458
+ static assets: string;
2459
+ static format: "esm" | "cjs";
2460
+ static packages: "external" | "bundle";
2461
+ static sourcemap: boolean;
2462
+ static handle(): Promise<void>;
2463
+ }
2464
+
2465
+ declare class GenerateCommand extends Command {
2466
+ static commandName: string;
2467
+ static description: string;
2468
+ static help: string[];
2469
+ /**
2470
+ * The path where the command will be generated
2471
+ */
2472
+ static path: string;
2473
+ static name: string;
2474
+ static handle(): Promise<void>;
2475
+ static getCommandTemplate(): string;
2476
+ }
2477
+
2478
+ declare class GenerateControllerCommand extends Command {
2479
+ static commandName: string;
2480
+ static description: string;
2481
+ static help: string[];
2482
+ static controllerName: string;
2483
+ static path: string;
2484
+ static handle(): Promise<void>;
2485
+ static getControllerTemplate(): string;
2486
+ }
2487
+
2488
+ declare class GenerateCron extends Command {
2489
+ static commandName: string;
2490
+ static description: string;
2491
+ static help: string[];
2492
+ static fileName: string;
2493
+ static path: string;
2494
+ static handle(): Promise<void>;
2495
+ static getCronTemplate(): string;
2496
+ }
2497
+
2498
+ declare class GenerateMiddlewareCommand extends Command {
2499
+ static commandName: string;
2500
+ static description: string;
2501
+ static help: string[];
2502
+ static middlewareName: string;
2503
+ static path: string;
2504
+ static handle(): Promise<void>;
2505
+ static getMiddlewareTemplate(): string;
2506
+ }
2507
+
2508
+ declare class GenerateMqttCommand extends Command {
2509
+ static commandName: string;
2510
+ static description: string;
2511
+ static help: string[];
2512
+ static path: string;
2513
+ static topic: string;
2514
+ static handle(): Promise<void>;
2515
+ static getMqttTemplate(isValidLiteral: boolean): string;
2516
+ }
2517
+
2518
+ declare class GeneratePluginCommand extends Command {
2519
+ static commandName: string;
2520
+ static description: string;
2521
+ static help: string[];
2522
+ static pluginName: string;
2523
+ static pluginPath: string;
2524
+ static handle(): Promise<void>;
2525
+ static getPluginTemplate(): string;
2526
+ }
2527
+
2528
+ declare class GenerateQueueCommand extends Command {
2529
+ static commandName: string;
2530
+ static description: string;
2531
+ static help: string[];
2532
+ static queueName: string;
2533
+ static path: string;
2534
+ static provider: string;
2535
+ static handle(): Promise<void>;
2536
+ static getQueueTemplate(isValidLiteral: boolean): string;
2537
+ }
2538
+
2539
+ declare class InitCommand extends Command {
2540
+ static commandName: string;
2541
+ static description: string;
2542
+ static help: string[];
2543
+ static srcPath: string;
2544
+ static typescript: boolean;
2545
+ static mqtt: boolean;
2546
+ static cron: boolean;
2547
+ static devDependencies: string[];
2548
+ static handle(): Promise<void>;
2549
+ static getServerTemplate(): string;
2550
+ static getIndexTemplate(): string;
2551
+ static getMqttConfigTemplate(): string;
2552
+ static getCronConfigTemplate(): string;
2553
+ }
2554
+
2555
+ declare class InitQueueCommand extends Command {
2556
+ static commandName: string;
2557
+ static description: string;
2558
+ static help: string[];
2559
+ static queueType: "bullmq" | "sqs" | "pgboss";
2560
+ static outputPath: string;
2561
+ static queueDependencies: Record<string, string[]>;
2562
+ static handle(): Promise<void>;
2563
+ static getConfigTemplate(): string;
2564
+ static getBullMQTemplate(): string;
2565
+ static getSQSTemplate(): string;
2566
+ static getPGBossTemplate(): string;
2567
+ }
2568
+
2569
+ declare class ListCommand extends Command {
2570
+ static commandName: string;
2571
+ static description: string;
2572
+ static help: string[];
2573
+ static handle(): Promise<void>;
2574
+ private static groupByCategory;
2575
+ private static displayCategorizedCommands;
2576
+ }
2577
+
2578
+ declare class ServeCommand extends Command {
2579
+ static commandName: string;
2580
+ static description: string;
2581
+ static help: string[];
2582
+ static runtime: RunTimeType;
2583
+ static options: CommandOptions;
2584
+ static entry: string;
2585
+ static denoImportMap?: string;
2586
+ static handle(): Promise<void>;
2587
+ private static handleNodeHotReload;
2588
+ }
2589
+
2590
+ declare class SetupStorageCommand extends Command {
2591
+ static commandName: string;
2592
+ static description: string;
2593
+ static help: string[];
2594
+ static storageType: string;
2595
+ static outputPath: string;
2596
+ static handle(): Promise<void>;
2597
+ private static getDependencies;
2598
+ private static checkMissingDependencies;
2599
+ private static createStorageSetup;
2600
+ private static getConfigTemplate;
2601
+ }
2602
+
2603
+ declare const baseCommands: (typeof BuildCommand | typeof GenerateCommand | typeof GenerateControllerCommand | typeof GenerateCron | typeof GenerateMiddlewareCommand | typeof GenerateMqttCommand | typeof GeneratePluginCommand | typeof GenerateQueueCommand | typeof InitCommand | typeof InitQueueCommand | typeof ListCommand | typeof ServeCommand | typeof SetupStorageCommand)[];
2604
+ /**
2605
+ * Singleton that registers all commands and provides a way to execute them.
2606
+ * Commands are loaded from the commands directory, and are expected to have a default export with the command class that extends the base command class.
2607
+ * Commands can be run both as `.js` or `.ts` files. If the file is a ts file `typescript` npm package must be installed.
2608
+ * You can use the `CommandRegistry.setCommandsPattern` method to change the pattern of the commands to load.
2609
+ * @example
2610
+ * // commands/test.ts
2611
+ * export default class TestCommand extends Command {
2612
+ * static name = "test";
2613
+ * async handle() {
2614
+ * console.log("Test command");
2615
+ * }
2616
+ * }
2617
+ */
2618
+ declare class CommandRegistry {
2619
+ private commands;
2620
+ private builtInCommands;
2621
+ static commandsPattern: string;
2622
+ static logger: pino.Logger<string, boolean>;
2623
+ /**
2624
+ * Private constructor to prevent direct instantiation
2625
+ * @internal Not meant to be used outside by the user
2626
+ */
2627
+ private constructor();
2628
+ static getInstance(): CommandRegistry;
2629
+ static setCommandsPattern(pattern: string): void;
2630
+ getCommand(name: string): typeof Command | null;
2631
+ getCommands(): (typeof Command)[];
2632
+ getBuiltInCommands(): (typeof Command)[];
2633
+ getUserDefinedCommands(): (typeof Command)[];
2634
+ isBuiltInCommand(commandName: string): boolean;
2635
+ loadCommands(commandsPattern: string): Promise<void>;
2636
+ }
2637
+ declare const commandRegistry: CommandRegistry;
2638
+
2639
+ declare class NativeHash {
2640
+ private readonly ITERATIONS;
2641
+ private readonly SALT_LENGTH;
2642
+ private readonly KEY_LENGTH;
2643
+ hash(data: string): Promise<string>;
2644
+ compare(hash: string, data: string): Promise<boolean>;
2645
+ private encodeBase64;
2646
+ private decodeBase64;
2647
+ }
2648
+ declare const hash: NativeHash;
2649
+
2650
+ declare const asyncStorage: AsyncLocalStorage<Record<string, any>>;
2651
+ /**
2652
+ * Async local storage plugin middleware, used to store data in the request context
2653
+ */
2654
+ declare const asyncLocalStorage: (ctxSetters: AsyncLocalStorageContextSetters) => ServerRouteMiddleware;
2655
+
2656
+ type LocalStorageProviderOptions = {
2657
+ /**
2658
+ * The directory to store the files
2659
+ */
2660
+ directory: string;
2661
+ };
2662
+ /**
2663
+ * Local storage provider, stores files in the local filesystem
2664
+ * Note: This provider does not support signed URLs (getDownloadUrl/getUploadUrl)
2665
+ */
2666
+ declare class LocalStorageProvider implements StorageInterface {
2667
+ private readonly options;
2668
+ private wasDirectoryEnsured;
2669
+ constructor(options: LocalStorageProviderOptions);
2670
+ getDownloadUrl(_key: string, _expiresInSeconds?: number): Promise<string>;
2671
+ getUploadUrl(_key: string, _expiresInSeconds?: number): Promise<string>;
2672
+ listObjects(prefix?: string): Promise<string[]>;
2673
+ getObject<R extends ReturnType$1 = "raw">(key: string, returnType?: R): Promise<ReturnTypeMap<R>>;
2674
+ putObject<T = Uint8Array>(key: string, value: T, _contentType?: string): Promise<void>;
2675
+ deleteObject(key: string): Promise<void>;
2676
+ private listFilesRecursively;
2677
+ private readDirectory;
2678
+ private ensureDirectoryExists;
2679
+ }
2680
+
2681
+ type S3ClientConfig = ConstructorParameters<typeof S3Client>[0];
2682
+ type S3StorageProviderOptions = {
2683
+ s3ClientConfig: S3ClientConfig & {
2684
+ bucketName: string;
2685
+ };
2686
+ /**
2687
+ * The cloudfront options (optional), allows to get the cloudfront signed url for an object, enables the `getDownloadUrl` method that throws an error if not configured
2688
+ */
2689
+ cloudfrontOptions?: {
2690
+ /**
2691
+ * The CloudFront distribution domain name (e.g., 'd1234567890.cloudfront.net')
2692
+ */
2693
+ domainName: string;
2694
+ /**
2695
+ * The CloudFront key pair ID
2696
+ */
2697
+ keyPairId: string;
2698
+ /**
2699
+ * The private key in PEM format for signing URLs
2700
+ */
2701
+ privateKey: string;
2702
+ };
2703
+ };
2704
+ declare class S3StorageProvider implements StorageInterface {
2705
+ private s3Lib;
2706
+ private s3PresignerLib;
2707
+ private cloudfrontSignerLib;
2708
+ private s3Client;
2709
+ readonly options: S3StorageProviderOptions;
2710
+ constructor(options: S3StorageProviderOptions);
2711
+ getDownloadUrl(key: string, expiresInSeconds?: number): Promise<string>;
2712
+ getUploadUrl(key: string, expiresInSeconds?: number): Promise<string>;
2713
+ listObjects(prefix?: string): Promise<string[]>;
2714
+ getObject<R extends ReturnType$1 = "raw">(key: string, returnType?: R): Promise<ReturnTypeMap<R>>;
2715
+ putObject<T = Uint8Array>(key: string, value: T, contentType?: string): Promise<void>;
2716
+ deleteObject(key: string): Promise<void>;
2717
+ private ensureClient;
2718
+ }
2719
+
2720
+ type ReturnType$1 = "raw" | "text" | "stream";
2721
+ type ReturnTypeMap<T extends ReturnType$1> = T extends "raw" ? Uint8Array : T extends "text" ? string : T extends "stream" ? ReadableStream : never;
2722
+ /**
2723
+ * High level storage interface, provides a unified way to interact with different storage providers
2724
+ */
2725
+ interface StorageInterface {
2726
+ /**
2727
+ * Get the download signed url of the object
2728
+ * @param key - The key of the object
2729
+ * @returns The download signed url of the object
2730
+ */
2731
+ getDownloadUrl: (key: string, expiresInSeconds?: number) => Promise<string>;
2732
+ /**
2733
+ * Get the upload signed url of the object
2734
+ * @param key - The key of the object
2735
+ * @returns The upload signed url of the object
2736
+ */
2737
+ getUploadUrl: (key: string, expiresInSeconds?: number) => Promise<string>;
2738
+ /**
2739
+ * List the objects from the storage
2740
+ * @param prefix - The prefix of the objects
2741
+ * @returns The objects from the storage
2742
+ */
2743
+ listObjects: (prefix?: string) => Promise<string[]>;
2744
+ /**
2745
+ * Get the object from the storage
2746
+ * @param key - The key of the object
2747
+ * @throws If no file is found for the given key
2748
+ * @returns The object from the storage
2749
+ */
2750
+ getObject: <R extends ReturnType$1 = "raw">(key: string, returnType: R) => Promise<ReturnTypeMap<R>>;
2751
+ /**
2752
+ * Put the object into the storage
2753
+ * @param key - The key of the object
2754
+ * @param value - The value of the object
2755
+ * @param contentType - The content type of the object
2756
+ * @returns The object from the storage
2757
+ */
2758
+ putObject: <T = Uint8Array>(key: string, value: T, contentType?: string) => Promise<void>;
2759
+ /**
2760
+ * Delete the object from the storage
2761
+ * @param key - The key of the object
2762
+ * @returns The object from the storage
2763
+ */
2764
+ deleteObject: (key: string) => Promise<void>;
2765
+ }
2766
+ type StorageOptions<T extends BaseStorageProviderOptions> = {
2767
+ /**
2768
+ * The default provider to use
2769
+ */
2770
+ defaultProvider: keyof T;
2771
+ };
2772
+ /**
2773
+ * Mapping of the storage provider options
2774
+ */
2775
+ interface BaseStorageProviderOptions {
2776
+ local?: LocalStorageProvider;
2777
+ s3?: S3StorageProvider;
2778
+ azureBlobStorage?: AzureBlobStorageProvider;
2779
+ }
2780
+ /**
2781
+ * Custom storage providers
2782
+ */
2783
+ interface CustomStorageProviderOptions {
2784
+ [key: string]: StorageInterface;
2785
+ }
2786
+ type StorageProviderOptions = CustomStorageProviderOptions & BaseStorageProviderOptions;
2787
+
2788
+ type BlobStorageProviderOptions = {
2789
+ /**
2790
+ * The container name
2791
+ */
2792
+ containerName: string;
2793
+ /**
2794
+ * The connection string to the storage account
2795
+ */
2796
+ connectionString: string;
2797
+ /**
2798
+ * The storage account name
2799
+ */
2800
+ storageAccountName: string;
2801
+ /**
2802
+ * The storage account key
2803
+ */
2804
+ storageAccountKey: string;
2805
+ };
2806
+ declare class AzureBlobStorageProvider implements StorageInterface {
2807
+ private readonly options;
2808
+ private azureBlobLib;
2809
+ private blobServiceClient;
2810
+ private containerClient;
2811
+ private sharedKeyCredential;
2812
+ constructor(options: BlobStorageProviderOptions);
2813
+ getDownloadUrl(key: string, expiresInSeconds?: number): Promise<string>;
2814
+ getUploadUrl(key: string, expiresInSeconds?: number): Promise<string>;
2815
+ listObjects(prefix?: string): Promise<string[]>;
2816
+ getObject<R extends ReturnType$1 = "raw">(key: string, returnType?: R): Promise<ReturnTypeMap<R>>;
2817
+ putObject<T = Uint8Array>(key: string, value: T, contentType?: string): Promise<void>;
2818
+ deleteObject(key: string): Promise<void>;
2819
+ private ensureClient;
2820
+ }
2821
+
2822
+ declare class Storage<T extends StorageProviderOptions> implements StorageInterface {
2823
+ private readonly providerOptions;
2824
+ private readonly defaultProvider;
2825
+ private readonly providerMap;
2826
+ constructor(providerOptions: T, storageOptions: StorageOptions<T>);
2827
+ /**
2828
+ * Use a specific provider
2829
+ * @param provider - The provider to use
2830
+ * @returns The storage instance
2831
+ */
2832
+ use(provider: keyof T): StorageInterface;
2833
+ getDownloadUrl(key: string, expiresInSeconds?: number): Promise<string>;
2834
+ getUploadUrl(key: string, expiresInSeconds?: number): Promise<string>;
2835
+ listObjects(prefix?: string): Promise<string[]>;
2836
+ getObject<R extends ReturnType$1 = "raw">(key: string, returnType?: R): Promise<ReturnTypeMap<R>>;
2837
+ putObject<T = Buffer<ArrayBufferLike>>(key: string, value: T, contentType?: string): Promise<void>;
2838
+ deleteObject(key: string): Promise<void>;
2839
+ }
2840
+
2841
+ /**
2842
+ * Base class for all plugins.
2843
+ *
2844
+ * Plugins are used to extend the functionality of the server.
2845
+ *
2846
+ * @example
2847
+ * ```ts
2848
+ * import { Server, BasePlugin } from "balda";
2849
+ *
2850
+ * export class MyPlugin extends BasePlugin {
2851
+ * async handle(): Promise<ServerRouteMiddleware> {
2852
+ * return async (req, res, next) => {
2853
+ * console.log("My plugin is running");
2854
+ * await next();
2855
+ * };
2856
+ * }
2857
+ * }
2858
+ *
2859
+ * const server = new Server();
2860
+ * server.use(new MyPlugin().handle());
2861
+ * ```
2862
+ *
2863
+ * @abstract
2864
+ */
2865
+ declare abstract class BasePlugin {
2866
+ abstract handle(...args: any[]): Promise<ServerRouteMiddleware>;
2867
+ }
2868
+
2869
+ /**
2870
+ * Compression middleware for gzip compression of response bodies
2871
+ *
2872
+ * @param options Compression middleware options
2873
+ */
2874
+ declare const compression: (options?: CompressionOptions) => ServerRouteMiddleware;
2875
+
2876
+ /**
2877
+ * Cookie middleware for parsing and setting cookies, must be used in order to use the cookie methods on the request and response objects
2878
+ *
2879
+ * @param options Cookie middleware options
2880
+ */
2881
+ declare const cookie: (options?: CookieMiddlewareOptions) => ServerRouteMiddleware;
2882
+
2883
+ /**
2884
+ * CORS plugin
2885
+ *
2886
+ * ⚠️ SECURITY WARNING: By default, this plugin allows ALL origins ('*').
2887
+ * For production environments, explicitly configure allowed origins.
2888
+ *
2889
+ * @param options CORS options (all optional)
2890
+ *
2891
+ * @example
2892
+ * // Development (permissive)
2893
+ * cors()
2894
+ *
2895
+ * @example
2896
+ * // Production (secure)
2897
+ * cors({
2898
+ * origin: ['https://example.com', 'https://app.example.com'],
2899
+ * credentials: true
2900
+ * })
2901
+ */
2902
+ declare const cors: (options?: CorsOptions) => ServerRouteMiddleware;
2903
+
2904
+ /**
2905
+ * Converts an Express middleware to a Balda middleware
2906
+ */
2907
+ declare function expressMiddleware(expressHandler: RequestHandler, basePath?: string): ServerRouteMiddleware;
2908
+ /**
2909
+ * Converts an Express handler to a Balda handler
2910
+ */
2911
+ declare function expressHandler(handler: RequestHandler, basePath?: string): ServerRouteHandler;
2912
+ /**
2913
+ * Mounts an Express router at a specific base path
2914
+ * This extracts all routes from the Express router and registers them with Balda
2915
+ */
2916
+ declare function mountExpressRouter(basePath: string, expressRouter: Router$1): void;
2917
+ /**
2918
+ * Creates an Express adapter that provides a use method for mounting Express middleware/routers
2919
+ *
2920
+ * @example
2921
+ * ```ts
2922
+ * import AdminJS from 'adminjs'
2923
+ * import AdminJSExpress from '@adminjs/express'
2924
+ * import { createExpressAdapter } from 'balda'
2925
+ *
2926
+ * const admin = new AdminJS({...})
2927
+ * const adminRouter = AdminJSExpress.buildRouter(admin)
2928
+ *
2929
+ * const server = new Server()
2930
+ * const express = createExpressAdapter(server)
2931
+ * express.use('/admin', adminRouter)
2932
+ * ```
2933
+ */
2934
+ declare function createExpressAdapter(server: {
2935
+ use: (...middlewares: ServerRouteMiddleware[]) => void;
2936
+ }): {
2937
+ use(pathOrMiddleware: string | RequestHandler | Router$1, maybeMiddleware?: RequestHandler | Router$1): void;
2938
+ };
2939
+
2940
+ /**
2941
+ * Middleware to handle multipart/form-data file uploads with security validations.
2942
+ * - Validates files against `FilePluginOptions`: size limits, file count, MIME types.
2943
+ * - Sanitizes filenames to prevent path traversal attacks.
2944
+ * - Uses cryptographically secure random filenames (UUID) in temporary storage.
2945
+ * - Stores uploaded files in a runtime-agnostic temporary directory and exposes them via `req.files`.
2946
+ * - Automatically cleans up temporary files after request completion or on error.
2947
+ * - Can be used as global middleware or route-specific middleware.
2948
+ */
2949
+ declare const fileParser: (options?: FilePluginOptions) => ServerRouteMiddleware;
2950
+
2951
+ /**
2952
+ * Sets common HTTP security headers
2953
+ * @param options Helmet options (all optional)
2954
+ */
2955
+ declare const helmet: (options?: HelmetOptions) => ServerRouteMiddleware;
2956
+
2957
+ /**
2958
+ * Middleware to parse the JSON body of the request. GET, DELETE and OPTIONS requests are not parsed.
2959
+ * @param options - The options for the JSON middleware.
2960
+ * @param options.sizeLimit - The maximum size of the JSON body. Default: 100kb
2961
+ */
2962
+ declare const json: (options?: JsonOptions) => ServerRouteMiddleware;
2963
+
2964
+ /**
2965
+ * Logs the request and response of the handler, can be set both on a specific route or on a global middleware.
2966
+ * @warning Only json objects and strings are logged from the request and response.
2967
+ */
2968
+ declare const log: (options?: LogOptions) => ServerRouteMiddleware;
2969
+
2970
+ /**
2971
+ * Method override middleware for supporting HTTP verbs like PUT/DELETE in clients that don't support them
2972
+ *
2973
+ * @param options Method override middleware options
2974
+ */
2975
+ declare const methodOverride: (options?: MethodOverrideOptions) => ServerRouteMiddleware;
2976
+
2977
+ /**
2978
+ * Rate limiter plugin
2979
+ * Rate limiter is a plugin that limits the number of requests to a resource.
2980
+ * It can be used to protect a resource from abuse.
2981
+ * @param keyOptions Rate limiter key options, tells the middleware how to retrieve the key from the request in to discriminate what to rate limit (all optional, defaults to ip)
2982
+ * @param storageOptions Rate limiter storage options, tells the middleware how to store the rate limit data (all optional, defaults to memory)
2983
+ */
2984
+ declare const rateLimiter: (keyOptions?: RateLimiterKeyOptions, storageOptions?: StorageOptions$1) => ServerRouteMiddleware;
2985
+
2986
+ /**
2987
+ * Session plugin middleware, used to store the session in the request and response objects
2988
+ * Uses cookies to send the session id
2989
+ * @warning Must be used after the cookie middleware
2990
+ * @param options Session options
2991
+ * @param options.name The name of the session cookie
2992
+ * @param options.ttl The TTL of the session in seconds
2993
+ * @param options.store The store to use for the session
2994
+ * @param options.cookie The cookie options
2995
+ */
2996
+ declare const session: (options?: SessionOptions) => ServerRouteMiddleware;
2997
+
2998
+ /**
2999
+ * Creates a static file serving middleware and registers all routes for the given path
3000
+ * @param options - The options for serving static files
3001
+ * @param options.source - The file system directory path where the assets are located
3002
+ * @param options.path - The URL path where the assets will be served
3003
+ * @param swaggerOptions - Optional swagger documentation options
3004
+ * @example
3005
+ * serveStatic({ source: 'tmp/assets', path: '/assets' }) // Serves from ./tmp/assets at /assets/*
3006
+ *
3007
+ * @example
3008
+ * serveStatic({ source: 'public', path: '/public' }) // Serves from ./public at /public/*
3009
+ */
3010
+ declare const serveStatic: (options: StaticPluginOptions, swaggerOptions?: SwaggerRouteOptions) => ServerRouteMiddleware;
3011
+ declare function getContentType(ext: string): string;
3012
+
3013
+ /**
3014
+ * Timeout plugin middleware, used to timeout the request if it takes too long
3015
+ * It fills the req.timeout property with true if the request times out
3016
+ * @param options Timeout options
3017
+ * @param options.ms The timeout in milliseconds
3018
+ * @param options.status The status code to return if the request times out
3019
+ * @param options.message The message to return if the request times out
3020
+ */
3021
+ declare const timeout: (options: TimeoutOptions) => ServerRouteMiddleware;
3022
+
3023
+ /**
3024
+ * Trust proxy plugin middleware, used to trust the proxy headers to get the client ip
3025
+ * @param options Trust proxy options (all optional)
3026
+ * @param options.trust Whether to trust the proxy headers
3027
+ * @param options.header The header name to read the client IP chain from
3028
+ * @param options.hop The hop to use to get the client IP
3029
+ */
3030
+ declare const trustProxy: (options?: TrustProxyOptions) => ServerRouteMiddleware;
3031
+
3032
+ /**
3033
+ * URL-encoded form data parser middleware
3034
+ * Parses application/x-www-form-urlencoded bodies and populates req.body
3035
+ * @param options URL-encoded parsing options
3036
+ * @param options.limit The maximum size of the URL-encoded body. Supports "5mb", "100kb" format. Defaults to "1mb".
3037
+ * @param options.extended Whether to parse extended syntax (objects and arrays). Defaults to false.
3038
+ * @param options.charset The character encoding to use when parsing. Defaults to 'utf8'.
3039
+ * @param options.allowEmpty Whether to allow empty values. Defaults to true.
3040
+ * @param options.parameterLimit Maximum number of parameters to parse. Defaults to 1000.
3041
+ */
3042
+ declare const urlencoded: (options?: UrlEncodedOptions) => ServerRouteMiddleware;
3043
+
3044
+ type PolicyProvider = {
3045
+ [K: string]: (...args: any[]) => Promise<boolean> | boolean;
3046
+ };
3047
+ type PolicyMetadata = {
3048
+ scope: string;
3049
+ handler: string;
3050
+ manager: PolicyManager<any>;
3051
+ };
3052
+ type PolicyDecorator<T extends Record<string, PolicyProvider>> = <S extends keyof T & string, H extends keyof T[S] & string>(scope: S, handler: H) => (target: any, propertyKey?: string, descriptor?: PropertyDescriptor) => any;
3053
+
3054
+ declare class PolicyManager<T extends Record<string, PolicyProvider>> {
3055
+ private readonly providers;
3056
+ constructor(providers: T);
3057
+ /**
3058
+ * Creates a decorator for the policy manager with typed parameters
3059
+ */
3060
+ createDecorator(): PolicyDecorator<T>;
3061
+ /**
3062
+ * Checks if the user has access to the given scope and handler
3063
+ * @param scope - The scope to check access for
3064
+ * @param handler - The handler to check access for
3065
+ * @param args - The arguments to pass to the handler
3066
+ */
3067
+ canAccess<K extends keyof T, L extends T[K]>(scope: K, handler: keyof L, ...args: Parameters<T[K][keyof T[K]]>): ReturnType<T[K][keyof T[K]]>;
3068
+ }
3069
+
3070
+ declare const createPolicyDecorator: <T extends Record<string, PolicyProvider>>(manager: PolicyManager<T>) => PolicyDecorator<T>;
3071
+
3072
+ /**
3073
+ * Singleton main router instance that handles all route registrations inside the balda server
3074
+ */
3075
+ declare const router: ClientRouter;
3076
+
3077
+ export { ARG_SYMBOL, AzureBlobStorageProvider, BaseCron, BaseMqtt, BasePlugin, BaseQueue, type BaseStorageProviderOptions, type BlobStorageProviderOptions, BullMQConfiguration, type BullMQConfigurationOptions, BullMQPubSub, type BunTapOptions, Command, type CommandOptions, CommandRegistry, type CronSchedule, type CronScheduleParams, CronService, type CustomQueueConfiguration, type CustomStorageProviderOptions, type CustomValidationError, type DenoTapOptions, type ExpressAdapterOptions, type ExpressHandler, type ExpressRouter, type FileAllowedMimeType, GraphQL, type GraphQLContext, type GraphQLOptions, type GraphQLResolverFunction, type GraphQLResolverMap, type GraphQLResolverType, type GraphQLResolvers, type GraphQLSchemaInput, type GraphQLTypeDef, type HttpMethod, type HttpsOptions, LocalStorageProvider, type LocalStorageProviderOptions, type LoggerOptions, MockServer, type MockServerOptions, type MqttConnectionOptions, type MqttHandler, type MqttPublishOptions, MqttService, type MqttSubscribeOptions, type MqttSubscription, type MqttTopics, type NextFunction, type NodeHttpClient, type NodeServer, type NodeTapOptions, PGBossConfiguration, type PGBossConfigurationOptions, PGBossPubSub, type PGBossSendOptions, type PolicyDecorator, PolicyManager, type PolicyMetadata, type PolicyProvider, type PubSub, type PublishOptions, QueueManager, type QueueProvider, type QueueProviderKey, QueueService, type QueueTopic, type QueueTopicKey, Request$1 as Request, type ResolvedServerOptions, Response$1 as Response, type ReturnType$1 as ReturnType, type ReturnTypeMap, type RuntimeServer, type RuntimeServerMap, S3StorageProvider, type S3StorageProviderOptions, SQSConfiguration, type SQSConfigurationOptions, SQSPubSub, type SQSPublishOptions, type SerializeOptions, Server, type ServerConnectInput, type ServerErrorHandler, type ServerInterface, type ServerListenCallback, type ServerOptions, type ServerPlugin, type ServerRoute, type ServerRouteHandler, type ServerRouteMiddleware, type ServerTapOptions, type ServerTapOptionsBuilder, type SignalEvent, type StandardMethodOptions, type StaticPluginOptions, Storage, type StorageInterface, type StorageOptions, type StorageProviderOptions, VALIDATION_ERROR_SYMBOL, type ValidationOptions, arg, asyncLocalStorage, asyncStorage, baseCommands, commandRegistry, compression, controller, cookie, cors, createExpressAdapter, createPolicyDecorator, cron, defineLoggerConfig, defineQueueConfiguration, del, expressHandler, expressMiddleware, fileParser, flag, get, getContentType, hash, helmet, json, log, logger, methodOverride, middleware, mountExpressRouter, mqtt, patch, post, publish, put, queue, rateLimiter, router, serialize, serveStatic, session, setCronGlobalErrorHandler, setMqttGlobalErrorHandler, timeout, trustProxy, urlencoded, validate };