@guren/server 0.2.0-alpha.6 → 1.0.0-rc.11

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (54) hide show
  1. package/dist/Application-DtWDHXr1.d.ts +2110 -0
  2. package/dist/BroadcastManager-AkIWUGJo.d.ts +466 -0
  3. package/dist/CacheManager-BkvHEOZX.d.ts +244 -0
  4. package/dist/ConsoleKernel-CqCVrdZs.d.ts +207 -0
  5. package/dist/EventManager-CmIoLt7r.d.ts +207 -0
  6. package/dist/Gate-CNkBYf8m.d.ts +268 -0
  7. package/dist/HealthManager-DUyMIzsZ.d.ts +141 -0
  8. package/dist/I18nManager-Dtgzsf5n.d.ts +270 -0
  9. package/dist/LogManager-7mxnkaPM.d.ts +256 -0
  10. package/dist/MailManager-DpMvYiP9.d.ts +292 -0
  11. package/dist/Scheduler-BstvSca7.d.ts +469 -0
  12. package/dist/StorageManager-oZTHqaza.d.ts +337 -0
  13. package/dist/api-token-JOif2CtG.d.ts +1792 -0
  14. package/dist/app-key-CsBfRC_Q.d.ts +214 -0
  15. package/dist/auth/index.d.ts +418 -0
  16. package/dist/auth/index.js +6742 -0
  17. package/dist/authorization/index.d.ts +129 -0
  18. package/dist/authorization/index.js +621 -0
  19. package/dist/broadcasting/index.d.ts +233 -0
  20. package/dist/broadcasting/index.js +907 -0
  21. package/dist/cache/index.d.ts +233 -0
  22. package/dist/cache/index.js +817 -0
  23. package/dist/encryption/index.d.ts +222 -0
  24. package/dist/encryption/index.js +602 -0
  25. package/dist/events/index.d.ts +155 -0
  26. package/dist/events/index.js +330 -0
  27. package/dist/health/index.d.ts +185 -0
  28. package/dist/health/index.js +379 -0
  29. package/dist/i18n/index.d.ts +101 -0
  30. package/dist/i18n/index.js +597 -0
  31. package/dist/index-9_Jzj5jo.d.ts +7 -0
  32. package/dist/index.d.ts +2628 -619
  33. package/dist/index.js +22229 -3116
  34. package/dist/lambda/index.d.ts +156 -0
  35. package/dist/lambda/index.js +91 -0
  36. package/dist/logging/index.d.ts +50 -0
  37. package/dist/logging/index.js +557 -0
  38. package/dist/mail/index.d.ts +288 -0
  39. package/dist/mail/index.js +695 -0
  40. package/dist/mcp/index.d.ts +139 -0
  41. package/dist/mcp/index.js +382 -0
  42. package/dist/notifications/index.d.ts +271 -0
  43. package/dist/notifications/index.js +741 -0
  44. package/dist/queue/index.d.ts +423 -0
  45. package/dist/queue/index.js +958 -0
  46. package/dist/runtime/index.d.ts +93 -0
  47. package/dist/runtime/index.js +834 -0
  48. package/dist/scheduling/index.d.ts +41 -0
  49. package/dist/scheduling/index.js +836 -0
  50. package/dist/storage/index.d.ts +196 -0
  51. package/dist/storage/index.js +832 -0
  52. package/dist/vite/index.js +203 -3
  53. package/package.json +93 -6
  54. package/dist/chunk-FK2XQSBF.js +0 -160
@@ -0,0 +1,2110 @@
1
+ import * as hono from 'hono';
2
+ import { Context, MiddlewareHandler, Hono, ExecutionContext } from 'hono';
3
+ import { A as AuthManager, O as OAuthManager, a as AuthContext, b as ApiToken, C as CreateSessionMiddlewareOptions } from './api-token-JOif2CtG.js';
4
+ import { InlineConfig, ViteDevServer } from 'vite';
5
+ import { E as EventManager } from './EventManager-CmIoLt7r.js';
6
+ import { C as CacheManager } from './CacheManager-BkvHEOZX.js';
7
+ import { M as MailManager } from './MailManager-DpMvYiP9.js';
8
+ import { L as LogManager } from './LogManager-7mxnkaPM.js';
9
+ import { I as I18nManager } from './I18nManager-Dtgzsf5n.js';
10
+ import { B as BroadcastManager } from './BroadcastManager-AkIWUGJo.js';
11
+ import { E as Encrypter, A as AppKeyring } from './app-key-CsBfRC_Q.js';
12
+ import { S as StorageManager } from './StorageManager-oZTHqaza.js';
13
+ import { H as HealthManager } from './HealthManager-DUyMIzsZ.js';
14
+ import { S as Scheduler } from './Scheduler-BstvSca7.js';
15
+ import { G as Gate } from './Gate-CNkBYf8m.js';
16
+ import { M as Middleware } from './index-9_Jzj5jo.js';
17
+
18
+ declare const CSRF_TOKEN_KEY = "_csrf_token";
19
+ declare const CSRF_HEADER_NAME = "X-CSRF-TOKEN";
20
+ declare const CSRF_FORM_FIELD = "_token";
21
+ interface CsrfOptions {
22
+ /**
23
+ * Routes to exclude from CSRF protection.
24
+ * Supports exact paths ('/api/webhook') or patterns ('/api/*').
25
+ */
26
+ exclude?: string[];
27
+ /**
28
+ * Custom error handler when CSRF validation fails.
29
+ * Defaults to returning a 403 JSON response.
30
+ */
31
+ onError?: (ctx: Context) => Response | Promise<Response>;
32
+ /**
33
+ * HTTP methods that require CSRF token validation.
34
+ * Defaults to ['POST', 'PUT', 'PATCH', 'DELETE'].
35
+ */
36
+ methods?: string[];
37
+ /**
38
+ * Set the CSRF token as an `XSRF-TOKEN` cookie on every response.
39
+ * This enables Axios/Inertia.js to automatically read the cookie
40
+ * and send it back as the `X-XSRF-TOKEN` header.
41
+ * Defaults to true.
42
+ */
43
+ cookie?: boolean;
44
+ /**
45
+ * Cookie options when `cookie` is enabled.
46
+ */
47
+ cookieOptions?: {
48
+ path?: string;
49
+ secure?: boolean;
50
+ sameSite?: 'Strict' | 'Lax' | 'None';
51
+ };
52
+ }
53
+ /**
54
+ * Get the CSRF token from the current session.
55
+ * Creates a new token if one doesn't exist.
56
+ */
57
+ declare function getCsrfToken(ctx: Context): string;
58
+ /**
59
+ * Generate an HTML hidden input field containing the CSRF token.
60
+ */
61
+ declare function csrfField(ctx: Context): string;
62
+ /**
63
+ * Verify that the provided token matches the session's CSRF token.
64
+ */
65
+ declare function verifyCsrfToken(ctx: Context, token: string | undefined): boolean;
66
+ /**
67
+ * Creates a CSRF protection middleware.
68
+ *
69
+ * This middleware:
70
+ * - Generates and stores a CSRF token in the session for GET requests
71
+ * - Validates the CSRF token for state-changing HTTP methods (POST, PUT, PATCH, DELETE)
72
+ * - Supports token submission via form field (_token) or header (X-CSRF-TOKEN)
73
+ *
74
+ * @example
75
+ * ```ts
76
+ * import { createCsrfMiddleware } from '@guren/server'
77
+ *
78
+ * app.use(createSessionMiddleware())
79
+ * app.use(createCsrfMiddleware({
80
+ * exclude: ['/api/webhooks/*']
81
+ * }))
82
+ * ```
83
+ */
84
+ declare function createCsrfMiddleware(options?: CsrfOptions): MiddlewareHandler;
85
+
86
+ interface InertiaOptions {
87
+ readonly url?: string;
88
+ readonly version?: string;
89
+ readonly status?: number;
90
+ readonly headers?: HeadersInit;
91
+ readonly request?: Request;
92
+ readonly title?: string;
93
+ readonly entry?: string;
94
+ readonly importMap?: Record<string, string>;
95
+ readonly styles?: string[];
96
+ readonly ssr?: InertiaSsrOptions;
97
+ }
98
+ interface InertiaPagePayload {
99
+ component: string;
100
+ props: Record<string, unknown>;
101
+ url: string;
102
+ version?: string;
103
+ }
104
+ interface InertiaSsrContext {
105
+ page: InertiaPagePayload;
106
+ request?: Request;
107
+ manifest?: string;
108
+ }
109
+ interface InertiaSsrResult {
110
+ head: string[];
111
+ body: string;
112
+ }
113
+ type InertiaSsrRenderer = (context: InertiaSsrContext) => Promise<InertiaSsrResult> | InertiaSsrResult;
114
+ interface InertiaSsrOptions {
115
+ enabled?: boolean;
116
+ entry?: string;
117
+ manifest?: string;
118
+ render?: InertiaSsrRenderer;
119
+ }
120
+ declare function inertia(component: string, props: Record<string, unknown>, options?: InertiaOptions): Promise<Response>;
121
+
122
+ /**
123
+ * Application-level shared props shape for Inertia responses.
124
+ * Extend this interface in your app (via declaration merging) to type shared props.
125
+ */
126
+ interface InertiaSharedProps {
127
+ }
128
+ type SharedPropsDefault = Record<string, unknown>;
129
+ type ResolvedSharedInertiaProps = InertiaSharedProps extends Record<string, unknown> ? InertiaSharedProps : SharedPropsDefault;
130
+ type SharedInertiaPropsResolver<Props extends Record<string, unknown> = ResolvedSharedInertiaProps> = (ctx: Context) => Promise<Props> | Props;
131
+ declare function setInertiaSharedProps<Props extends Record<string, unknown> = ResolvedSharedInertiaProps>(resolverFn: SharedInertiaPropsResolver<Props> | null): void;
132
+
133
+ /**
134
+ * Parses the incoming request payload supporting both JSON bodies and form submissions.
135
+ * Falls back to an empty object if the payload cannot be parsed.
136
+ */
137
+ declare function parseRequestPayload(ctx: Context): Promise<Record<string, unknown>>;
138
+ interface ValidationIssueLike {
139
+ path: PropertyKey[];
140
+ message: string;
141
+ }
142
+ interface ValidationErrorLike {
143
+ issues: ValidationIssueLike[];
144
+ }
145
+ /**
146
+ * Converts a Zod-style validation error into a flat record usable by forms.
147
+ */
148
+ declare function formatValidationErrors(error: ValidationErrorLike, fallbackMessage?: string): Record<string, string>;
149
+
150
+ declare const VALIDATED_DATA_KEY = "guren:validated";
151
+ interface ValidationSchema<T = unknown> {
152
+ parse(data: unknown): T;
153
+ safeParse(data: unknown): {
154
+ success: true;
155
+ data: T;
156
+ } | {
157
+ success: false;
158
+ error: ValidationErrorLike;
159
+ };
160
+ }
161
+ interface ValidateRequestOptions {
162
+ /**
163
+ * Custom error handler when validation fails.
164
+ * Defaults to returning a 422 JSON response with formatted errors.
165
+ */
166
+ onError?: (ctx: Context, errors: Record<string, string>) => Response | Promise<Response>;
167
+ /**
168
+ * HTTP status code for validation errors.
169
+ * Defaults to 422 (Unprocessable Entity).
170
+ */
171
+ status?: number;
172
+ /**
173
+ * Fallback message when no field-specific errors are available.
174
+ */
175
+ fallbackMessage?: string;
176
+ }
177
+ /**
178
+ * Get validated data from the request context.
179
+ * Returns undefined if validation middleware hasn't run or validation failed.
180
+ */
181
+ declare function getValidatedData<T = Record<string, unknown>>(ctx: Context): T | undefined;
182
+ /**
183
+ * Creates a validation middleware that validates the request body against a Zod schema.
184
+ *
185
+ * @example
186
+ * ```ts
187
+ * import { z } from 'zod'
188
+ * import { validateRequest, getValidatedData } from '@guren/server'
189
+ *
190
+ * const CreateUserSchema = z.object({
191
+ * name: z.string().min(1),
192
+ * email: z.string().email(),
193
+ * })
194
+ *
195
+ * app.post('/users', validateRequest(CreateUserSchema), (c) => {
196
+ * const data = getValidatedData<z.infer<typeof CreateUserSchema>>(c)
197
+ * // data is typed and validated
198
+ * return c.json({ user: data })
199
+ * })
200
+ * ```
201
+ */
202
+ declare function validateRequest<T>(schema: ValidationSchema<T>, options?: ValidateRequestOptions): MiddlewareHandler;
203
+ /**
204
+ * Creates a validation middleware from a schema factory function.
205
+ * Useful when the schema depends on request context.
206
+ *
207
+ * @example
208
+ * ```ts
209
+ * app.post('/users/:role', validateRequestWith((ctx) => {
210
+ * const role = ctx.req.param('role')
211
+ * return role === 'admin' ? AdminSchema : UserSchema
212
+ * }), handler)
213
+ * ```
214
+ */
215
+ declare function validateRequestWith<T>(schemaFactory: (ctx: Context) => ValidationSchema<T>, options?: ValidateRequestOptions): MiddlewareHandler;
216
+ /**
217
+ * Validates data against a schema and throws if invalid.
218
+ * Useful for manual validation in handlers.
219
+ *
220
+ * @example
221
+ * ```ts
222
+ * app.post('/data', async (c) => {
223
+ * const payload = await parseRequestPayload(c)
224
+ * const data = validate(MySchema, payload)
225
+ * // throws ValidationError if invalid
226
+ * return c.json(data)
227
+ * })
228
+ * ```
229
+ */
230
+ declare function validate<T>(schema: ValidationSchema<T>, data: unknown): T;
231
+ /**
232
+ * Validates data against a schema and returns a result object.
233
+ * Does not throw on validation failure.
234
+ */
235
+ declare function validateSafe<T>(schema: ValidationSchema<T>, data: unknown): {
236
+ success: true;
237
+ data: T;
238
+ } | {
239
+ success: false;
240
+ errors: Record<string, string>;
241
+ };
242
+
243
+ interface HstsOptions {
244
+ /** Max age in seconds. */
245
+ maxAge: number;
246
+ /** Include subdomains. Default: false */
247
+ includeSubDomains?: boolean;
248
+ /** Enable HSTS preload. Default: false */
249
+ preload?: boolean;
250
+ }
251
+ interface SecurityHeadersOptions {
252
+ /** X-Frame-Options header. Set to false to disable. Default: 'SAMEORIGIN' */
253
+ frameOptions?: string | false;
254
+ /** X-Content-Type-Options header. Set to false to disable. Default: 'nosniff' */
255
+ contentTypeOptions?: string | false;
256
+ /** X-XSS-Protection header. Set to false to disable. Default: '0' */
257
+ xssProtection?: string | false;
258
+ /** Referrer-Policy header. Set to false to disable. Default: 'strict-origin-when-cross-origin' */
259
+ referrerPolicy?: string | false;
260
+ /** X-Permitted-Cross-Domain-Policies header. Set to false to disable. Default: 'none' */
261
+ crossDomainPolicies?: string | false;
262
+ /** Strict-Transport-Security header. Default: false (disabled) */
263
+ hsts?: HstsOptions | false;
264
+ }
265
+ /**
266
+ * Middleware that sets common HTTP security headers on every response.
267
+ *
268
+ * @example
269
+ * ```ts
270
+ * import { createSecurityHeaders } from '@guren/core'
271
+ *
272
+ * app.use('*', createSecurityHeaders())
273
+ *
274
+ * // With HSTS enabled
275
+ * app.use('*', createSecurityHeaders({
276
+ * hsts: { maxAge: 31536000, includeSubDomains: true },
277
+ * }))
278
+ *
279
+ * // Disable specific headers
280
+ * app.use('*', createSecurityHeaders({
281
+ * frameOptions: false,
282
+ * xssProtection: false,
283
+ * }))
284
+ * ```
285
+ */
286
+ declare function createSecurityHeaders(options?: SecurityHeadersOptions): MiddlewareHandler;
287
+
288
+ interface HostAuthorizationOptions {
289
+ /** Allowed hosts. Supports exact matches and wildcard subdomains (e.g., '*.example.com'). */
290
+ allowedHosts: string[];
291
+ /** Paths to exclude from host checking (e.g., ['/healthcheck', '/up']). */
292
+ exclude?: string[];
293
+ /** Custom response when host is not authorized. Default: 403 Forbidden. */
294
+ onError?: (ctx: Context) => Response | Promise<Response>;
295
+ }
296
+ /**
297
+ * Middleware that validates the Host header against an allowed list.
298
+ * Protects against DNS rebinding and host header attacks.
299
+ *
300
+ * @example
301
+ * ```ts
302
+ * import { createHostAuthorizationMiddleware } from '@guren/core'
303
+ *
304
+ * app.use('*', createHostAuthorizationMiddleware({
305
+ * allowedHosts: ['example.com', '*.example.com', 'localhost:3000'],
306
+ * exclude: ['/healthcheck'],
307
+ * }))
308
+ * ```
309
+ */
310
+ declare function createHostAuthorizationMiddleware(options: HostAuthorizationOptions): MiddlewareHandler;
311
+
312
+ /**
313
+ * Serialized job data stored in the queue.
314
+ */
315
+ interface QueuedJob<T = unknown> {
316
+ /**
317
+ * Unique job identifier.
318
+ */
319
+ id: string;
320
+ /**
321
+ * Job class name.
322
+ */
323
+ name: string;
324
+ /**
325
+ * Job payload data.
326
+ */
327
+ payload: T;
328
+ /**
329
+ * Queue name this job belongs to.
330
+ */
331
+ queue: string;
332
+ /**
333
+ * Number of times this job has been attempted.
334
+ */
335
+ attempts: number;
336
+ /**
337
+ * Maximum number of attempts before failing permanently.
338
+ */
339
+ maxAttempts: number;
340
+ /**
341
+ * When the job becomes available for processing.
342
+ */
343
+ availableAt: Date;
344
+ /**
345
+ * When the job was created.
346
+ */
347
+ createdAt: Date;
348
+ /**
349
+ * When the job was reserved by a worker (null if not reserved).
350
+ */
351
+ reservedAt: Date | null;
352
+ /**
353
+ * Last error message if the job failed.
354
+ */
355
+ lastError?: string;
356
+ }
357
+ /**
358
+ * Failed job record.
359
+ */
360
+ interface FailedJob<T = unknown> extends QueuedJob<T> {
361
+ /**
362
+ * When the job failed.
363
+ */
364
+ failedAt: Date;
365
+ /**
366
+ * Error that caused the failure.
367
+ */
368
+ error: string;
369
+ /**
370
+ * Stack trace of the error.
371
+ */
372
+ stack?: string;
373
+ }
374
+ /**
375
+ * Queue driver interface.
376
+ * Implement this to create a custom queue backend.
377
+ */
378
+ interface QueueDriver {
379
+ /**
380
+ * Push a job onto the queue.
381
+ */
382
+ push(job: QueuedJob): Promise<void>;
383
+ /**
384
+ * Pop the next available job from the queue.
385
+ * Returns null if no jobs are available.
386
+ */
387
+ pop(queue: string): Promise<QueuedJob | null>;
388
+ /**
389
+ * Release a job back onto the queue (for retry).
390
+ * @param job - The job to release
391
+ * @param delayMs - Delay before the job becomes available again
392
+ */
393
+ release(job: QueuedJob, delayMs?: number): Promise<void>;
394
+ /**
395
+ * Delete a job from the queue.
396
+ */
397
+ delete(jobId: string): Promise<void>;
398
+ /**
399
+ * Mark a job as failed and move to failed jobs.
400
+ */
401
+ fail(job: QueuedJob, error: Error): Promise<void>;
402
+ /**
403
+ * Get the number of jobs in a queue.
404
+ */
405
+ size(queue: string): Promise<number>;
406
+ /**
407
+ * Get failed jobs.
408
+ */
409
+ getFailedJobs(queue?: string): Promise<FailedJob[]>;
410
+ /**
411
+ * Retry a failed job.
412
+ */
413
+ retryFailedJob(jobId: string): Promise<void>;
414
+ /**
415
+ * Delete a failed job.
416
+ */
417
+ deleteFailedJob(jobId: string): Promise<void>;
418
+ /**
419
+ * Clear all jobs (for testing).
420
+ */
421
+ clear(): Promise<void>;
422
+ }
423
+ /**
424
+ * Options for creating a job.
425
+ */
426
+ interface JobOptions {
427
+ /**
428
+ * Queue to dispatch the job to.
429
+ * @default 'default'
430
+ */
431
+ queue?: string;
432
+ /**
433
+ * Delay in milliseconds before the job is available.
434
+ * @default 0
435
+ */
436
+ delay?: number;
437
+ /**
438
+ * Maximum number of attempts.
439
+ * @default 3
440
+ */
441
+ maxAttempts?: number;
442
+ }
443
+ /**
444
+ * Worker options.
445
+ */
446
+ interface WorkerOptions {
447
+ /**
448
+ * Queues to process (in priority order).
449
+ * @default ['default']
450
+ */
451
+ queues?: string[];
452
+ /**
453
+ * Sleep time in milliseconds when no jobs are available.
454
+ * @default 1000
455
+ */
456
+ sleep?: number;
457
+ /**
458
+ * Maximum number of jobs to process before stopping.
459
+ * Set to 0 for unlimited.
460
+ * @default 0
461
+ */
462
+ maxJobs?: number;
463
+ /**
464
+ * Timeout for each job in milliseconds.
465
+ * @default 60000
466
+ */
467
+ timeout?: number;
468
+ /**
469
+ * Stop the worker when no jobs are available.
470
+ * Useful for one-shot processing or testing.
471
+ * @default false
472
+ */
473
+ stopWhenEmpty?: boolean;
474
+ }
475
+ /**
476
+ * Job handler function type.
477
+ */
478
+ type JobHandler<T = unknown> = (payload: T) => void | Promise<void>;
479
+ /**
480
+ * Job failure handler function type.
481
+ */
482
+ type JobFailureHandler<T = unknown> = (payload: T, error: Error) => void | Promise<void>;
483
+
484
+ /**
485
+ * Set the global queue driver.
486
+ */
487
+ declare function setQueueDriver(driver: QueueDriver): void;
488
+ /**
489
+ * Get the global queue driver.
490
+ */
491
+ declare function getQueueDriver(): QueueDriver | null;
492
+ /**
493
+ * Base class for defining jobs.
494
+ *
495
+ * @example
496
+ * ```ts
497
+ * class SendWelcomeEmailJob extends Job<{ userId: string }> {
498
+ * static queue = 'emails'
499
+ * static maxAttempts = 5
500
+ *
501
+ * async handle({ userId }: { userId: string }): Promise<void> {
502
+ * const user = await User.find(userId)
503
+ * await mail.to(user.email).template(WelcomeEmail, user).send()
504
+ * }
505
+ *
506
+ * async failed({ userId }: { userId: string }, error: Error): Promise<void> {
507
+ * console.error(`Failed to send welcome email to user ${userId}:`, error)
508
+ * }
509
+ * }
510
+ *
511
+ * // Dispatch the job
512
+ * await SendWelcomeEmailJob.dispatch({ userId: '123' })
513
+ *
514
+ * // Dispatch with delay
515
+ * await SendWelcomeEmailJob.dispatchAfter(60000, { userId: '123' })
516
+ * ```
517
+ */
518
+ declare abstract class Job<T = unknown> {
519
+ /**
520
+ * The queue this job should be dispatched to.
521
+ * @default 'default'
522
+ */
523
+ static queue: string;
524
+ /**
525
+ * Maximum number of times the job should be attempted.
526
+ * @default 3
527
+ */
528
+ static maxAttempts: number;
529
+ /**
530
+ * Backoff strategy for retries.
531
+ * - 'exponential': 2^attempt * 1000ms (1s, 2s, 4s, 8s, ...)
532
+ * - 'linear': attempt * 1000ms (1s, 2s, 3s, 4s, ...)
533
+ * - number: fixed delay in milliseconds
534
+ * @default 'exponential'
535
+ */
536
+ static backoff: 'exponential' | 'linear' | number;
537
+ protected make<K extends keyof ServiceBindings>(key: K): ServiceBindings[K];
538
+ protected make<TService>(key: string): TService;
539
+ /**
540
+ * Handle the job.
541
+ * Override this method to define job logic.
542
+ */
543
+ abstract handle(payload: T): void | Promise<void>;
544
+ /**
545
+ * Called when the job fails permanently (after all retries exhausted).
546
+ * Override this method to handle failures.
547
+ */
548
+ failed?(payload: T, error: Error): void | Promise<void>;
549
+ /**
550
+ * Dispatch the job to the queue.
551
+ *
552
+ * @param payload - Job payload data
553
+ * @param options - Optional dispatch options
554
+ */
555
+ static dispatch<T>(this: JobClass<T>, payload: T, options?: JobOptions): Promise<string>;
556
+ /**
557
+ * Dispatch the job after a delay.
558
+ *
559
+ * @param delayMs - Delay in milliseconds
560
+ * @param payload - Job payload data
561
+ * @param options - Optional dispatch options (delay is overridden)
562
+ */
563
+ static dispatchAfter<T>(this: JobClass<T>, delayMs: number, payload: T, options?: Omit<JobOptions, 'delay'>): Promise<string>;
564
+ /**
565
+ * Calculate the retry delay based on backoff strategy.
566
+ */
567
+ static calculateRetryDelay(attempts: number): number;
568
+ }
569
+ /**
570
+ * Job class constructor type.
571
+ */
572
+ interface JobClass<T = unknown> {
573
+ new (): Job<T>;
574
+ name: string;
575
+ queue: string;
576
+ maxAttempts: number;
577
+ backoff: 'exponential' | 'linear' | number;
578
+ dispatch(payload: T, options?: JobOptions): Promise<string>;
579
+ dispatchAfter(delayMs: number, payload: T, options?: Omit<JobOptions, 'delay'>): Promise<string>;
580
+ calculateRetryDelay(attempts: number): number;
581
+ }
582
+ /**
583
+ * Register a job class for the worker to use.
584
+ */
585
+ declare function registerJob<T>(jobClass: JobClass<T>): void;
586
+ /**
587
+ * Get a registered job class by name.
588
+ */
589
+ declare function getJob(name: string): JobClass | undefined;
590
+ /**
591
+ * Get all registered job classes.
592
+ */
593
+ declare function getRegisteredJobs(): Map<string, JobClass>;
594
+ /**
595
+ * Clear all registered jobs (for testing).
596
+ */
597
+ declare function clearJobRegistry(): void;
598
+
599
+ /**
600
+ * Queue driver factory function.
601
+ */
602
+ type QueueDriverFactory = () => QueueDriver;
603
+ /**
604
+ * Queue configuration.
605
+ */
606
+ interface QueueConfig {
607
+ /**
608
+ * Default driver name.
609
+ * @default 'memory'
610
+ */
611
+ default?: string;
612
+ /**
613
+ * Driver configurations.
614
+ */
615
+ drivers?: Record<string, QueueDriverFactory>;
616
+ }
617
+ /**
618
+ * Queue manager for handling multiple queue drivers.
619
+ *
620
+ * @example
621
+ * ```ts
622
+ * import { QueueManager, MemoryDriver, RedisDriver } from '@guren/server/queue'
623
+ * import { createRedisClient } from '@guren/server/redis'
624
+ *
625
+ * const redis = createRedisClient({ url: process.env.REDIS_URL })
626
+ *
627
+ * const queueManager = new QueueManager({
628
+ * default: 'redis',
629
+ * drivers: {
630
+ * memory: () => new MemoryDriver(),
631
+ * redis: () => new RedisDriver(redis),
632
+ * }
633
+ * })
634
+ *
635
+ * // Use the default driver
636
+ * const driver = queueManager.driver()
637
+ *
638
+ * // Use a specific driver
639
+ * const memoryDriver = queueManager.driver('memory')
640
+ * ```
641
+ */
642
+ declare class QueueManager {
643
+ private readonly defaultDriver;
644
+ private readonly driverFactories;
645
+ private readonly resolvedDrivers;
646
+ constructor(config?: QueueConfig);
647
+ /**
648
+ * Get a queue driver by name.
649
+ * Returns the default driver if no name is specified.
650
+ */
651
+ driver(name?: string): QueueDriver;
652
+ /**
653
+ * Register a custom driver factory.
654
+ */
655
+ registerDriver(name: string, factory: QueueDriverFactory): void;
656
+ /**
657
+ * Check if a driver is registered.
658
+ */
659
+ hasDriver(name: string): boolean;
660
+ /**
661
+ * Get the default driver name.
662
+ */
663
+ getDefaultDriverName(): string;
664
+ /**
665
+ * Get all registered driver names.
666
+ */
667
+ getDriverNames(): string[];
668
+ /**
669
+ * Set the default driver and update global driver.
670
+ */
671
+ setDefaultDriver(name: string): void;
672
+ }
673
+ /**
674
+ * Create a queue manager with default configuration.
675
+ */
676
+ declare function createQueueManager(config?: QueueConfig): QueueManager;
677
+
678
+ /**
679
+ * Base notification class.
680
+ *
681
+ * @example
682
+ * ```typescript
683
+ * class OrderShipped extends Notification {
684
+ * static shouldQueue = true
685
+ * static queue = 'notifications'
686
+ *
687
+ * constructor(private order: Order) {
688
+ * super()
689
+ * }
690
+ *
691
+ * via(notifiable: Notifiable): string[] {
692
+ * return ['mail', 'database']
693
+ * }
694
+ *
695
+ * toMail(notifiable: Notifiable): NotificationMailMessage {
696
+ * return {
697
+ * subject: `Order #${this.order.id} shipped`,
698
+ * html: '<p>Your order is on its way!</p>',
699
+ * }
700
+ * }
701
+ *
702
+ * toDatabase(notifiable: Notifiable): Record<string, unknown> {
703
+ * return {
704
+ * orderId: this.order.id,
705
+ * message: 'Your order has shipped',
706
+ * }
707
+ * }
708
+ * }
709
+ * ```
710
+ */
711
+ declare abstract class Notification {
712
+ /**
713
+ * Whether this notification should be queued.
714
+ */
715
+ static shouldQueue: boolean;
716
+ /**
717
+ * The queue name for this notification.
718
+ */
719
+ static queue?: string;
720
+ /**
721
+ * Delay in milliseconds before sending.
722
+ */
723
+ static delay?: number;
724
+ /**
725
+ * Unique notification ID.
726
+ */
727
+ readonly id: string;
728
+ /**
729
+ * When the notification was created.
730
+ */
731
+ readonly createdAt: Date;
732
+ constructor();
733
+ /**
734
+ * Get the notification's delivery channels.
735
+ */
736
+ abstract via(notifiable: Notifiable): string[];
737
+ /**
738
+ * Get the mail representation of the notification.
739
+ */
740
+ toMail?(notifiable: Notifiable): NotificationMailMessage;
741
+ /**
742
+ * Get the database representation of the notification.
743
+ */
744
+ toDatabase?(notifiable: Notifiable): Record<string, unknown>;
745
+ /**
746
+ * Get the Slack representation of the notification.
747
+ */
748
+ toSlack?(notifiable: Notifiable): SlackMessage;
749
+ /**
750
+ * Get the array representation of the notification.
751
+ * Used as a fallback for any channel.
752
+ */
753
+ toArray?(notifiable: Notifiable): Record<string, unknown>;
754
+ /**
755
+ * Get the notification type (default: class name).
756
+ */
757
+ get type(): string;
758
+ /**
759
+ * Check if the notification should be sent to the given notifiable.
760
+ * Override to add custom logic.
761
+ */
762
+ shouldSend(_notifiable: Notifiable): boolean | Promise<boolean>;
763
+ /**
764
+ * Generate a unique notification ID.
765
+ */
766
+ protected generateId(): string;
767
+ /**
768
+ * Get static queue configuration.
769
+ */
770
+ static getQueueConfig(): {
771
+ shouldQueue: boolean;
772
+ queue?: string;
773
+ delay?: number;
774
+ };
775
+ }
776
+
777
+ /**
778
+ * Notification channel interface.
779
+ */
780
+ interface NotificationChannel {
781
+ readonly name: string;
782
+ send(notifiable: Notifiable, notification: Notification): Promise<void>;
783
+ }
784
+ /**
785
+ * Notifiable entity interface.
786
+ */
787
+ interface Notifiable {
788
+ /**
789
+ * Get the notification routing information for a given channel.
790
+ */
791
+ routeNotificationFor(channel: string): string | null;
792
+ /**
793
+ * Database notifications (optional).
794
+ */
795
+ notifications?: DatabaseNotification[];
796
+ }
797
+ /**
798
+ * Database notification record.
799
+ */
800
+ interface DatabaseNotification {
801
+ id: string;
802
+ type: string;
803
+ notifiableId: string | number;
804
+ notifiableType: string;
805
+ data: Record<string, unknown>;
806
+ readAt: Date | null;
807
+ createdAt: Date;
808
+ }
809
+ /**
810
+ * Mail message for notifications.
811
+ */
812
+ interface NotificationMailMessage {
813
+ subject: string;
814
+ html?: string;
815
+ text?: string;
816
+ from?: string;
817
+ replyTo?: string;
818
+ cc?: string | string[];
819
+ bcc?: string | string[];
820
+ attachments?: NotificationAttachment[];
821
+ }
822
+ /**
823
+ * Notification attachment.
824
+ */
825
+ interface NotificationAttachment {
826
+ filename: string;
827
+ content?: string | Buffer;
828
+ path?: string;
829
+ contentType?: string;
830
+ }
831
+ /**
832
+ * Slack message for notifications.
833
+ */
834
+ interface SlackMessage {
835
+ text?: string;
836
+ blocks?: SlackBlock[];
837
+ attachments?: SlackAttachment[];
838
+ channel?: string;
839
+ username?: string;
840
+ icon_emoji?: string;
841
+ icon_url?: string;
842
+ }
843
+ /**
844
+ * Slack block.
845
+ */
846
+ interface SlackBlock {
847
+ type: string;
848
+ text?: {
849
+ type: string;
850
+ text: string;
851
+ emoji?: boolean;
852
+ };
853
+ elements?: unknown[];
854
+ accessory?: unknown;
855
+ fields?: Array<{
856
+ type: string;
857
+ text: string;
858
+ }>;
859
+ [key: string]: unknown;
860
+ }
861
+ /**
862
+ * Slack attachment.
863
+ */
864
+ interface SlackAttachment {
865
+ color?: string;
866
+ fallback?: string;
867
+ pretext?: string;
868
+ author_name?: string;
869
+ author_link?: string;
870
+ author_icon?: string;
871
+ title?: string;
872
+ title_link?: string;
873
+ text?: string;
874
+ fields?: Array<{
875
+ title: string;
876
+ value: string;
877
+ short?: boolean;
878
+ }>;
879
+ image_url?: string;
880
+ thumb_url?: string;
881
+ footer?: string;
882
+ footer_icon?: string;
883
+ ts?: number;
884
+ }
885
+ /**
886
+ * Notification channel factory.
887
+ */
888
+ interface NotificationChannelFactory {
889
+ (config: Record<string, unknown>): NotificationChannel;
890
+ }
891
+ /**
892
+ * Notification manager options.
893
+ */
894
+ interface NotificationManagerOptions {
895
+ channels?: Record<string, NotificationChannel>;
896
+ channelFactories?: Record<string, NotificationChannelFactory>;
897
+ }
898
+ /**
899
+ * Database channel options.
900
+ */
901
+ interface DatabaseChannelOptions {
902
+ /**
903
+ * Callback to store the notification.
904
+ */
905
+ store?: (notifiable: Notifiable, notification: DatabaseNotification) => Promise<void>;
906
+ }
907
+ /**
908
+ * Sent notification record (for testing).
909
+ */
910
+ interface SentNotification {
911
+ notifiable: Notifiable;
912
+ notification: Notification;
913
+ channels: string[];
914
+ timestamp: Date;
915
+ }
916
+ /**
917
+ * Notification class type.
918
+ */
919
+ interface NotificationClass<T extends Notification = Notification> {
920
+ new (...args: unknown[]): T;
921
+ shouldQueue?: boolean;
922
+ queue?: string;
923
+ delay?: number;
924
+ getQueueConfig?: () => {
925
+ shouldQueue: boolean;
926
+ queue?: string;
927
+ delay?: number;
928
+ };
929
+ }
930
+
931
+ /**
932
+ * Notification manager for sending notifications through multiple channels.
933
+ *
934
+ * @example
935
+ * ```typescript
936
+ * const notifications = new NotificationManager()
937
+ *
938
+ * notifications
939
+ * .registerChannel('mail', new MailChannel(mailManager))
940
+ * .registerChannel('database', new DatabaseChannel())
941
+ * .registerChannel('slack', new SlackChannel(webhookUrl))
942
+ *
943
+ * // Send notification
944
+ * await notifications.send(user, new OrderShipped(order))
945
+ *
946
+ * // Send to multiple users
947
+ * await notifications.sendToMany(admins, new NewUserRegistered(user))
948
+ * ```
949
+ */
950
+ declare class NotificationManager {
951
+ protected channels: Map<string, NotificationChannel>;
952
+ protected channelFactories: Map<string, NotificationChannelFactory>;
953
+ protected resolvedChannels: Map<string, NotificationChannel>;
954
+ constructor(options?: NotificationManagerOptions);
955
+ /**
956
+ * Register a notification channel.
957
+ */
958
+ registerChannel(name: string, channel: NotificationChannel): this;
959
+ /**
960
+ * Register a notification channel factory.
961
+ */
962
+ registerChannelFactory(name: string, factory: NotificationChannelFactory): this;
963
+ /**
964
+ * Get a notification channel by name.
965
+ */
966
+ channel(name: string): NotificationChannel;
967
+ /**
968
+ * Check if a channel is registered.
969
+ */
970
+ hasChannel(name: string): boolean;
971
+ /**
972
+ * Get all registered channel names.
973
+ */
974
+ getChannelNames(): string[];
975
+ /**
976
+ * Send a notification to a notifiable entity.
977
+ * Respects queue configuration on the notification class.
978
+ */
979
+ send(notifiable: Notifiable, notification: Notification): Promise<void>;
980
+ /**
981
+ * Send a notification immediately (bypasses queue).
982
+ */
983
+ sendNow(notifiable: Notifiable, notification: Notification): Promise<void>;
984
+ /**
985
+ * Queue a notification for later delivery.
986
+ */
987
+ protected queue(notifiable: Notifiable, notification: Notification, queueConfig: {
988
+ queue?: string;
989
+ delay?: number;
990
+ }): Promise<void>;
991
+ /**
992
+ * Send notification to multiple notifiables.
993
+ */
994
+ sendToMany(notifiables: Notifiable[], notification: Notification): Promise<void>;
995
+ /**
996
+ * Send notification immediately to multiple notifiables.
997
+ */
998
+ sendNowToMany(notifiables: Notifiable[], notification: Notification): Promise<void>;
999
+ /**
1000
+ * Serialize notifiable for queue storage.
1001
+ */
1002
+ protected serializeNotifiable(notifiable: Notifiable): SerializedNotifiable;
1003
+ /**
1004
+ * Serialize notification for queue storage.
1005
+ */
1006
+ protected serializeNotification(notification: Notification): SerializedNotification;
1007
+ /**
1008
+ * Create the notification job class.
1009
+ */
1010
+ protected createNotificationJob(): typeof SendNotificationJob;
1011
+ }
1012
+ /**
1013
+ * Payload for queued notifications.
1014
+ */
1015
+ interface SendNotificationPayload {
1016
+ notifiableData: SerializedNotifiable;
1017
+ notificationData: SerializedNotification;
1018
+ notificationType: string;
1019
+ }
1020
+ interface SerializedNotifiable {
1021
+ type: string;
1022
+ data: Record<string, unknown>;
1023
+ }
1024
+ interface SerializedNotification {
1025
+ type: string;
1026
+ id: string;
1027
+ data: Record<string, unknown>;
1028
+ }
1029
+ /**
1030
+ * Job for sending queued notifications.
1031
+ */
1032
+ declare class SendNotificationJob extends Job<SendNotificationPayload> {
1033
+ static jobName: string;
1034
+ static queue: string;
1035
+ static maxAttempts: number;
1036
+ static notificationManager: NotificationManager | null;
1037
+ handle(payload: SendNotificationPayload): Promise<void>;
1038
+ }
1039
+ /**
1040
+ * Set the global notification manager.
1041
+ */
1042
+ declare function setNotificationManager(manager: NotificationManager): void;
1043
+ /**
1044
+ * Get the global notification manager.
1045
+ */
1046
+ declare function getNotificationManager(): NotificationManager;
1047
+ /**
1048
+ * Create a notification manager.
1049
+ */
1050
+ declare function createNotificationManager(options?: NotificationManagerOptions): NotificationManager;
1051
+
1052
+ /**
1053
+ * Error response structure.
1054
+ */
1055
+ interface ErrorResponse {
1056
+ message: string;
1057
+ errors?: Record<string, string[]>;
1058
+ stack?: string;
1059
+ exception?: string;
1060
+ }
1061
+ /**
1062
+ * Exception handler options.
1063
+ */
1064
+ interface ExceptionHandlerOptions {
1065
+ /**
1066
+ * Whether to show detailed error information.
1067
+ * Default: true in development, false in production.
1068
+ */
1069
+ debug?: boolean;
1070
+ /**
1071
+ * Custom debug detection function.
1072
+ */
1073
+ isDebug?: () => boolean;
1074
+ }
1075
+ /**
1076
+ * Exception reporter callback.
1077
+ */
1078
+ type ExceptionReporter = (error: Error) => void | Promise<void>;
1079
+ /**
1080
+ * Exception renderer callback.
1081
+ */
1082
+ type ExceptionRenderer<T extends Error = Error> = (error: T, ctx: Context) => Response | Promise<Response>;
1083
+ /**
1084
+ * Exception class type.
1085
+ */
1086
+ type ExceptionClass<T extends Error = Error> = new (...args: any[]) => T;
1087
+ /**
1088
+ * Renderer registration.
1089
+ */
1090
+ interface RendererRegistration {
1091
+ errorClass: ExceptionClass;
1092
+ renderer: ExceptionRenderer;
1093
+ }
1094
+
1095
+ /**
1096
+ * Exception handler for centralized error handling.
1097
+ *
1098
+ * @example
1099
+ * ```typescript
1100
+ * const handler = new ExceptionHandler({ debug: false })
1101
+ *
1102
+ * // Report exceptions (e.g., to Sentry)
1103
+ * handler.report(async (error) => {
1104
+ * await sentry.captureException(error)
1105
+ * })
1106
+ *
1107
+ * // Custom renderer for validation errors
1108
+ * handler.render(ValidationException, (error, ctx) => {
1109
+ * return ctx.json({ errors: error.errors }, 422)
1110
+ * })
1111
+ *
1112
+ * // Don't report 404 errors
1113
+ * handler.dontReport(NotFoundHttpException)
1114
+ *
1115
+ * // Use as middleware
1116
+ * app.use('*', handler.middleware())
1117
+ * ```
1118
+ */
1119
+ declare class ExceptionHandler {
1120
+ /**
1121
+ * Exception reporters.
1122
+ */
1123
+ protected reporters: ExceptionReporter[];
1124
+ /**
1125
+ * Exception renderers.
1126
+ */
1127
+ protected renderers: RendererRegistration[];
1128
+ /**
1129
+ * Exception classes to not report.
1130
+ */
1131
+ protected dontReportClasses: ExceptionClass[];
1132
+ /**
1133
+ * Handler options.
1134
+ */
1135
+ protected options: ExceptionHandlerOptions;
1136
+ constructor(options?: ExceptionHandlerOptions);
1137
+ /**
1138
+ * Register an exception reporter.
1139
+ * Reporters are called for every exception (unless in dontReport list).
1140
+ */
1141
+ report(callback: ExceptionReporter): this;
1142
+ /**
1143
+ * Register a custom renderer for an exception type.
1144
+ */
1145
+ render<T extends Error>(errorClass: ExceptionClass<T>, renderer: ExceptionRenderer<T>): this;
1146
+ /**
1147
+ * Add an exception class to the don't report list.
1148
+ */
1149
+ dontReport(errorClass: ExceptionClass): this;
1150
+ /**
1151
+ * Check if debug mode is enabled.
1152
+ */
1153
+ shouldShowDetails(): boolean;
1154
+ /**
1155
+ * Handle an exception.
1156
+ */
1157
+ handle(error: Error, ctx: Context): Promise<Response>;
1158
+ /**
1159
+ * Report an exception to all reporters.
1160
+ */
1161
+ protected reportException(error: Error): Promise<void>;
1162
+ /**
1163
+ * Check if an exception should not be reported.
1164
+ */
1165
+ protected shouldNotReport(error: Error): boolean;
1166
+ protected matchesErrorClass(error: Error, errorClass: ExceptionClass): boolean;
1167
+ /**
1168
+ * Render an exception to a response.
1169
+ */
1170
+ protected renderException(error: Error, ctx: Context): Promise<Response>;
1171
+ /**
1172
+ * Default exception rendering.
1173
+ */
1174
+ protected renderDefaultException(error: Error, ctx: Context): Response;
1175
+ /**
1176
+ * Determine whether the request expects an HTML response.
1177
+ * Returns false for Inertia, XHR, and JSON API requests so they
1178
+ * continue to receive JSON error payloads.
1179
+ */
1180
+ protected wantsHtmlResponse(ctx: Context): boolean;
1181
+ /**
1182
+ * Create middleware for exception handling.
1183
+ */
1184
+ middleware(): Middleware;
1185
+ }
1186
+ /**
1187
+ * Create an exception handler.
1188
+ */
1189
+ declare function createExceptionHandler(options?: ExceptionHandlerOptions): ExceptionHandler;
1190
+ /**
1191
+ * Set the global exception handler.
1192
+ */
1193
+ declare function setExceptionHandler(handler: ExceptionHandler): void;
1194
+ /**
1195
+ * Get the global exception handler.
1196
+ */
1197
+ declare function getExceptionHandler(): ExceptionHandler;
1198
+ /**
1199
+ * Abort the request with an HTTP exception.
1200
+ */
1201
+ declare function abort(statusCode: number, message?: string, errors?: Record<string, string[]>): never;
1202
+ /**
1203
+ * Abort if condition is true.
1204
+ */
1205
+ declare function abortIf(condition: boolean, statusCode: number, message?: string): void;
1206
+ /**
1207
+ * Abort unless condition is true.
1208
+ */
1209
+ declare function abortUnless(condition: boolean, statusCode: number, message?: string): void;
1210
+
1211
+ /**
1212
+ * Type-safe service binding map.
1213
+ *
1214
+ * Maps service keys to their concrete types for type-safe resolution
1215
+ * via `container.make('key')`.
1216
+ *
1217
+ * @example
1218
+ * ```typescript
1219
+ * const events = container.make('events') // EventManager
1220
+ * const cache = container.make('cache') // CacheManager
1221
+ * ```
1222
+ */
1223
+ interface ServiceBindings {
1224
+ app: Application;
1225
+ hono: Hono;
1226
+ events: EventManager;
1227
+ cache: CacheManager;
1228
+ queue: QueueManager;
1229
+ mail: MailManager;
1230
+ log: LogManager;
1231
+ i18n: I18nManager;
1232
+ notifications: NotificationManager;
1233
+ broadcast: BroadcastManager;
1234
+ encrypter: Encrypter;
1235
+ 'app.keyring': AppKeyring;
1236
+ auth: AuthManager;
1237
+ oauth: OAuthManager;
1238
+ storage: StorageManager;
1239
+ health: HealthManager;
1240
+ scheduler: Scheduler;
1241
+ gate: Gate;
1242
+ 'exception.handler': ExceptionHandler;
1243
+ }
1244
+
1245
+ /** Structural type for DI containers, avoiding a hard dependency on Container. */
1246
+ interface ContainerLike {
1247
+ make(key: string): unknown;
1248
+ }
1249
+ /**
1250
+ * Duck-type interface for Zod-like schemas.
1251
+ * Allows validation without a direct Zod dependency.
1252
+ */
1253
+ interface ZodLikeSchema<T> {
1254
+ safeParse(data: unknown): {
1255
+ success: true;
1256
+ data: T;
1257
+ } | {
1258
+ success: false;
1259
+ error: {
1260
+ issues: Array<{
1261
+ path: PropertyKey[];
1262
+ message: string;
1263
+ }>;
1264
+ };
1265
+ };
1266
+ }
1267
+ /**
1268
+ * Result type for safe validation methods (discriminated union).
1269
+ */
1270
+ type SafeValidationResult<T> = {
1271
+ success: true;
1272
+ data: T;
1273
+ } | {
1274
+ success: false;
1275
+ errors: Record<string, string>;
1276
+ };
1277
+ type DefaultInertiaProps = Record<string, unknown>;
1278
+ type AuthPayload = Record<string, unknown> & {
1279
+ user: unknown;
1280
+ };
1281
+ type InertiaPageContractLike<Component extends string = string, Props extends DefaultInertiaProps = DefaultInertiaProps> = {
1282
+ id: Component;
1283
+ component?: Component;
1284
+ __props?: Props;
1285
+ };
1286
+ type InertiaResponseMarker<Component extends string, Props extends DefaultInertiaProps> = {
1287
+ __gurenInertia: {
1288
+ component: Component;
1289
+ props: Props;
1290
+ };
1291
+ };
1292
+ type InertiaResponse<Component extends string, Props extends DefaultInertiaProps> = Response & InertiaResponseMarker<Component, Props>;
1293
+ type InertiaWithProps = {
1294
+ __gurenInertia: {
1295
+ props: DefaultInertiaProps;
1296
+ };
1297
+ };
1298
+ type ExtractInertiaProps<T> = Awaited<T> extends infer R ? R extends InertiaWithProps ? R['__gurenInertia']['props'] : never : never;
1299
+ type InferInertiaProps<T> = [ExtractInertiaProps<T>] extends [never] ? DefaultInertiaProps : ExtractInertiaProps<T>;
1300
+ type ControllerInertiaProps<TController extends Controller, TAction extends keyof TController> = TController[TAction] extends (...args: any[]) => infer TResult ? InferInertiaProps<Awaited<TResult>> : DefaultInertiaProps;
1301
+ interface RedirectOptions {
1302
+ status?: number;
1303
+ headers?: HeadersInit;
1304
+ }
1305
+ type InertiaResponseOptions = Omit<InertiaOptions, 'url' | 'request'> & {
1306
+ url?: string;
1307
+ };
1308
+ type InertiaPageComponent<TPage extends InertiaPageContractLike> = TPage['id'];
1309
+ type InertiaPageProps<TPage extends InertiaPageContractLike> = NonNullable<TPage['__props']>;
1310
+ /**
1311
+ * Base controller inspired by Laravel's expressive API. Subclasses can access
1312
+ * the current Hono context through the protected `ctx` getter and rely on the
1313
+ * helper response builders for common patterns.
1314
+ *
1315
+ * Supports dependency injection via the `static inject` convention:
1316
+ * ```typescript
1317
+ * class PostController extends Controller {
1318
+ * static inject = ['cache', 'events'] as const
1319
+ * constructor(private cache: CacheManager, private events: EventManager) { super() }
1320
+ * }
1321
+ * ```
1322
+ */
1323
+ declare class Controller {
1324
+ /**
1325
+ * Dependencies to inject from the container.
1326
+ * Override in subclasses to declare required services.
1327
+ */
1328
+ static inject?: readonly string[];
1329
+ private context?;
1330
+ private parsedBody?;
1331
+ private resolvedModels?;
1332
+ private _container?;
1333
+ setContext(context: Context): void;
1334
+ /** @internal Called by the router to inject the DI container. */
1335
+ setContainer(container: ContainerLike): void;
1336
+ /**
1337
+ * Store a resolved model instance from route model binding.
1338
+ * @internal Called by the router, not intended for direct use.
1339
+ */
1340
+ setResolvedModel(modelClass: unknown, instance: unknown): void;
1341
+ /**
1342
+ * Retrieve a model instance resolved via route model binding.
1343
+ *
1344
+ * @example
1345
+ * ```typescript
1346
+ * // routes/web.ts
1347
+ * posts.get('/:id', { bind: { id: Post }, name: 'posts.show' }, [PostController, 'show'])
1348
+ *
1349
+ * // PostController.ts
1350
+ * async show() {
1351
+ * const post = this.model(Post) // typed as PostRecord
1352
+ * return this.inertia(pages.posts.Show, { post })
1353
+ * }
1354
+ * ```
1355
+ */
1356
+ protected model<T extends {
1357
+ findOrFail(...args: any[]): Promise<any>;
1358
+ }>(modelClass: T): Awaited<ReturnType<T['findOrFail']>>;
1359
+ protected get ctx(): Context;
1360
+ protected get request(): hono.HonoRequest<any, unknown>;
1361
+ protected get auth(): AuthContext;
1362
+ protected make<K extends keyof ServiceBindings>(key: K): ServiceBindings[K];
1363
+ protected make<T>(key: string): T;
1364
+ /**
1365
+ * Get the authenticated API token or throw AuthenticationException.
1366
+ *
1367
+ * @example
1368
+ * ```typescript
1369
+ * const { userId, abilities } = this.apiToken()
1370
+ * ```
1371
+ */
1372
+ protected apiToken(): {
1373
+ token: ApiToken;
1374
+ userId: string | number;
1375
+ abilities: string[];
1376
+ };
1377
+ /**
1378
+ * Get the authenticated user ID from the API token.
1379
+ *
1380
+ * @example
1381
+ * ```typescript
1382
+ * const userId = this.apiTokenUserId()
1383
+ * ```
1384
+ */
1385
+ protected apiTokenUserId(): string | number;
1386
+ protected inertia<TPage extends InertiaPageContractLike>(page: TPage, props: InertiaPageProps<TPage>, options?: InertiaResponseOptions): Promise<InertiaResponse<InertiaPageComponent<TPage>, InertiaPageProps<TPage> & ResolvedSharedInertiaProps>>;
1387
+ protected inertia<Component extends string, Props extends DefaultInertiaProps>(component: Component, props: Props, options?: InertiaResponseOptions): Promise<InertiaResponse<Component, Props & ResolvedSharedInertiaProps>>;
1388
+ protected json<T>(data: T, init?: ResponseInit): Response;
1389
+ protected text(body: string, init?: ResponseInit): Response;
1390
+ protected redirect(url: string, options?: RedirectOptions): Response;
1391
+ /**
1392
+ * Return a 204 No Content response.
1393
+ */
1394
+ protected noContent(): Response;
1395
+ /**
1396
+ * Return a 201 Created response with JSON data.
1397
+ */
1398
+ protected created<T>(data?: T, init?: ResponseInit): Response;
1399
+ /**
1400
+ * Return a 202 Accepted response with optional JSON data.
1401
+ */
1402
+ protected accepted<T>(data?: T, init?: ResponseInit): Response;
1403
+ private jsonStatus;
1404
+ /**
1405
+ * Get a specific input value from the request body or query parameters.
1406
+ * Body values take precedence over query parameters.
1407
+ */
1408
+ protected input<T = unknown>(key: string, defaultValue?: T): Promise<T | undefined>;
1409
+ /**
1410
+ * Get a query parameter value.
1411
+ */
1412
+ protected query(key: string, defaultValue?: string): string | undefined;
1413
+ /**
1414
+ * Get only the specified keys from the request body.
1415
+ */
1416
+ protected only(...keys: string[]): Promise<Record<string, unknown>>;
1417
+ /**
1418
+ * Get all request body values except the specified keys.
1419
+ */
1420
+ protected except(...keys: string[]): Promise<Record<string, unknown>>;
1421
+ /**
1422
+ * Check if a key exists in the request body.
1423
+ */
1424
+ protected has(key: string): Promise<boolean>;
1425
+ /** Flatten query string arrays to scalar values for cleaner schema usage. */
1426
+ private flattenQueries;
1427
+ /**
1428
+ * Validate the request body against a Zod-like schema.
1429
+ * Throws ValidationException on failure.
1430
+ *
1431
+ * @example
1432
+ * ```typescript
1433
+ * const data = await this.validateBody(CreatePostSchema)
1434
+ * ```
1435
+ */
1436
+ protected validateBody<T>(schema: ZodLikeSchema<T>): Promise<T>;
1437
+ /**
1438
+ * Validate query parameters against a Zod-like schema.
1439
+ * Throws ValidationException on failure.
1440
+ *
1441
+ * @example
1442
+ * ```typescript
1443
+ * const { page } = this.validateQuery(PageQuerySchema)
1444
+ * ```
1445
+ */
1446
+ protected validateQuery<T>(schema: ZodLikeSchema<T>): T;
1447
+ /**
1448
+ * Validate route parameters against a Zod-like schema.
1449
+ * Throws ValidationException on failure.
1450
+ *
1451
+ * @example
1452
+ * ```typescript
1453
+ * const { id } = this.validateParams(PostIdParamSchema)
1454
+ * ```
1455
+ */
1456
+ protected validateParams<T>(schema: ZodLikeSchema<T>): T;
1457
+ /**
1458
+ * Validate the request body against a Zod-like schema without throwing.
1459
+ * Returns a discriminated union: `{ success: true, data }` or `{ success: false, errors }`.
1460
+ *
1461
+ * @example
1462
+ * ```typescript
1463
+ * const result = await this.validateBodySafe(CreatePostSchema)
1464
+ * if (!result.success) {
1465
+ * return this.inertia(pages.posts.New, { errors: result.errors }, { status: 422 })
1466
+ * }
1467
+ * const { title, body } = result.data
1468
+ * ```
1469
+ */
1470
+ protected validateBodySafe<T>(schema: ZodLikeSchema<T>): Promise<SafeValidationResult<T>>;
1471
+ /**
1472
+ * Validate query parameters against a Zod-like schema without throwing.
1473
+ * Returns a discriminated union: `{ success: true, data }` or `{ success: false, errors }`.
1474
+ */
1475
+ protected validateQuerySafe<T>(schema: ZodLikeSchema<T>): SafeValidationResult<T>;
1476
+ /**
1477
+ * Validate route parameters against a Zod-like schema without throwing.
1478
+ * Returns a discriminated union: `{ success: true, data }` or `{ success: false, errors }`.
1479
+ */
1480
+ protected validateParamsSafe<T>(schema: ZodLikeSchema<T>): SafeValidationResult<T>;
1481
+ private runValidation;
1482
+ private runValidationSafe;
1483
+ private getBody;
1484
+ }
1485
+
1486
+ /**
1487
+ * Service factory function.
1488
+ */
1489
+ type ServiceFactory<T> = (container: Container) => T;
1490
+ /**
1491
+ * Service class constructor.
1492
+ */
1493
+ type ServiceClass<T> = new (...args: unknown[]) => T;
1494
+ /**
1495
+ * Service binding configuration.
1496
+ */
1497
+ interface ServiceBinding {
1498
+ factory: ServiceFactory<unknown>;
1499
+ singleton: boolean;
1500
+ instance?: unknown;
1501
+ }
1502
+ /**
1503
+ * Contextual binding builder interface.
1504
+ */
1505
+ interface ContextualBindingBuilder {
1506
+ needs(abstract: string): ContextualNeedsBuilder;
1507
+ }
1508
+ /**
1509
+ * Contextual needs builder interface.
1510
+ */
1511
+ interface ContextualNeedsBuilder {
1512
+ give<T>(factory: ServiceFactory<T> | T): void;
1513
+ }
1514
+ /**
1515
+ * Contextual binding configuration.
1516
+ */
1517
+ interface ContextualBinding {
1518
+ concrete: string;
1519
+ needs: string;
1520
+ factory: ServiceFactory<unknown>;
1521
+ }
1522
+ /**
1523
+ * Service provider options.
1524
+ */
1525
+ interface ServiceProviderOptions {
1526
+ /**
1527
+ * Whether this provider should be deferred.
1528
+ */
1529
+ deferred?: boolean;
1530
+ /**
1531
+ * Services this provider provides (for deferred loading).
1532
+ */
1533
+ provides?: string[];
1534
+ }
1535
+ /**
1536
+ * Provider interface for container-based service providers.
1537
+ */
1538
+ interface Provider {
1539
+ register?(context: unknown): void | Promise<void>;
1540
+ boot?(context: unknown): void | Promise<void>;
1541
+ }
1542
+ /**
1543
+ * Service provider class type.
1544
+ */
1545
+ interface ServiceProviderClass {
1546
+ new (container: Container): Provider;
1547
+ deferred?: boolean;
1548
+ provides?: string[];
1549
+ }
1550
+
1551
+ /**
1552
+ * Dependency injection container with type-safe service resolution.
1553
+ *
1554
+ * @example
1555
+ * ```typescript
1556
+ * const container = new Container()
1557
+ *
1558
+ * // Register services
1559
+ * container.singleton('events', (c) => new EventManager())
1560
+ * container.instance('config', loadConfig())
1561
+ *
1562
+ * // Type-safe resolution (known bindings)
1563
+ * const events = container.make('events') // EventManager
1564
+ *
1565
+ * // Generic resolution (custom bindings)
1566
+ * const db = container.make<Database>('db')
1567
+ * ```
1568
+ */
1569
+ declare class Container {
1570
+ protected bindings: Map<string, ServiceBinding>;
1571
+ protected aliases: Map<string, string>;
1572
+ protected tags: Map<string, Set<string>>;
1573
+ protected contextualBindings: ContextualBinding[];
1574
+ protected resolvingStack: string[];
1575
+ protected scopedInstances: Map<string, unknown>[];
1576
+ protected fakes: Map<string, unknown>;
1577
+ /** @internal Used by ProviderManager to resolve deferred providers on demand */
1578
+ deferredProviderLoader: ((service: string) => Promise<void>) | null;
1579
+ /**
1580
+ * Bind a service to the container.
1581
+ * Each resolution creates a new instance.
1582
+ */
1583
+ bind<T>(key: string, factory: ServiceFactory<T>): this;
1584
+ /**
1585
+ * Bind a singleton service to the container.
1586
+ * Only one instance is created and reused.
1587
+ */
1588
+ singleton<T>(key: string, factory: ServiceFactory<T>): this;
1589
+ /**
1590
+ * Bind an existing instance to the container.
1591
+ */
1592
+ instance<T>(key: string, value: T): this;
1593
+ /**
1594
+ * Resolve a service from the container.
1595
+ *
1596
+ * Known service keys (from ServiceBindings) are automatically typed:
1597
+ * ```typescript
1598
+ * container.make('events') // EventManager
1599
+ * container.make('cache') // CacheManager
1600
+ * ```
1601
+ *
1602
+ * Custom keys require an explicit type parameter:
1603
+ * ```typescript
1604
+ * container.make<MyService>('myService')
1605
+ * ```
1606
+ */
1607
+ make<K extends keyof ServiceBindings>(key: K): ServiceBindings[K];
1608
+ make<T>(key: string): T;
1609
+ /**
1610
+ * Resolve a service with additional parameters.
1611
+ */
1612
+ makeWith<T>(key: string, params: Record<string, unknown>): T;
1613
+ /**
1614
+ * Check if a service is bound in the container.
1615
+ */
1616
+ has(key: string): boolean;
1617
+ /**
1618
+ * Create an alias for a service.
1619
+ */
1620
+ alias(alias: string, key: string): this;
1621
+ /**
1622
+ * Tag multiple services with a tag name.
1623
+ */
1624
+ tag(keys: string[], tagName: string): this;
1625
+ /**
1626
+ * Resolve all services with a given tag.
1627
+ */
1628
+ tagged<T = unknown>(tagName: string): T[];
1629
+ /**
1630
+ * Define a contextual binding.
1631
+ */
1632
+ when(concrete: string): ContextualBindingBuilder;
1633
+ /**
1634
+ * Run a callback within a scoped context.
1635
+ * Services resolved within the scope are cached and released when the scope ends.
1636
+ */
1637
+ scoped<T>(callback: () => T): T;
1638
+ /**
1639
+ * Run an async callback within a scoped context.
1640
+ */
1641
+ scopedAsync<T>(callback: () => Promise<T>): Promise<T>;
1642
+ /**
1643
+ * Replace a service binding with a fake instance for testing.
1644
+ * Returns a disposable that restores the original binding when disposed.
1645
+ *
1646
+ * @example
1647
+ * ```typescript
1648
+ * // Using 'using' declaration (auto-cleanup)
1649
+ * using _ = container.fake('events', fakeEventManager)
1650
+ *
1651
+ * // Manual cleanup
1652
+ * const restore = container.fake('mail', fakeMailManager)
1653
+ * // ... run tests ...
1654
+ * restore[Symbol.dispose]()
1655
+ * ```
1656
+ */
1657
+ fake<K extends keyof ServiceBindings>(key: K, instance: ServiceBindings[K]): Disposable;
1658
+ fake(key: string, instance: unknown): Disposable;
1659
+ /**
1660
+ * Check if a service is currently faked.
1661
+ */
1662
+ isFaked(key: string): boolean;
1663
+ /**
1664
+ * Remove all fakes.
1665
+ */
1666
+ clearFakes(): void;
1667
+ /**
1668
+ * Flush all resolved singleton instances.
1669
+ */
1670
+ flush(): void;
1671
+ /**
1672
+ * Remove a binding from the container.
1673
+ */
1674
+ forget(key: string): this;
1675
+ /**
1676
+ * Get all bound service keys.
1677
+ */
1678
+ getBindings(): string[];
1679
+ /**
1680
+ * Get all aliases.
1681
+ */
1682
+ getAliases(): Record<string, string>;
1683
+ /**
1684
+ * Get all tags.
1685
+ */
1686
+ getTags(): Record<string, string[]>;
1687
+ protected resolveAlias(key: string): string;
1688
+ protected findContextualBinding(needs: string): ServiceFactory<unknown> | null;
1689
+ }
1690
+ /**
1691
+ * Create a new container instance.
1692
+ */
1693
+ declare function createContainer(): Container;
1694
+ declare function setContainer(container: Container): void;
1695
+ declare function getContainer(): Container;
1696
+ declare function resolve<T = unknown>(key: string): T;
1697
+
1698
+ /**
1699
+ * Constructor type for Controller classes.
1700
+ * @template T - The controller type extending Controller
1701
+ */
1702
+ type ControllerConstructor<T extends Controller = Controller> = (new (...args: any[]) => T) & {
1703
+ inject?: readonly string[];
1704
+ };
1705
+ type ControllerMethod<T extends Controller> = {
1706
+ [K in keyof T]: T[K] extends (...args: any[]) => any ? K : never;
1707
+ }[keyof T] & string;
1708
+ type ControllerMethodFor<C extends ControllerConstructor> = ControllerMethod<InstanceType<C>>;
1709
+ type ControllerAction<C extends ControllerConstructor = ControllerConstructor> = [C, ControllerMethodFor<C>];
1710
+ type RouteResult = Response | string | number | boolean | Record<string, unknown> | Array<unknown> | null | void;
1711
+ /**
1712
+ * Handler for a route - either an inline function or a controller action tuple.
1713
+ */
1714
+ type RouteHandler<C extends ControllerConstructor = ControllerConstructor> = ((c: Context) => RouteResult | Promise<RouteResult>) | ControllerAction<C>;
1715
+ /**
1716
+ * Model binding resolver function.
1717
+ */
1718
+ type ModelBindingResolver = (value: string) => Promise<unknown>;
1719
+ /**
1720
+ * Model class with findOrFail static method.
1721
+ */
1722
+ interface BindableModel {
1723
+ findOrFail(id: unknown, key?: string): Promise<unknown>;
1724
+ }
1725
+ type SchemaLike<T = unknown> = ValidationSchema<T> | undefined;
1726
+ type InferSchema<TSchema extends SchemaLike<unknown>> = TSchema extends ValidationSchema<infer TValue> ? TValue : never;
1727
+ type RouteParamsFor<TSchema extends SchemaLike<unknown>> = [
1728
+ TSchema
1729
+ ] extends [ValidationSchema<any>] ? InferSchema<TSchema> : Record<string, string>;
1730
+ type RouteQueryFor<TSchema extends SchemaLike<unknown>> = [
1731
+ TSchema
1732
+ ] extends [ValidationSchema<any>] ? InferSchema<TSchema> : Record<string, string | undefined>;
1733
+ type RouteBodyFor<TSchema extends SchemaLike<unknown>> = [
1734
+ TSchema
1735
+ ] extends [ValidationSchema<any>] ? InferSchema<TSchema> : Record<string, unknown>;
1736
+ interface TypedRouteContext<TParamsSchema extends SchemaLike<unknown>, TQuerySchema extends SchemaLike<unknown>, TBodySchema extends SchemaLike<unknown>> {
1737
+ ctx: Context;
1738
+ params: RouteParamsFor<TParamsSchema>;
1739
+ query: RouteQueryFor<TQuerySchema>;
1740
+ body: RouteBodyFor<TBodySchema>;
1741
+ }
1742
+ type TypedRouteHandler<TParamsSchema extends SchemaLike<unknown>, TQuerySchema extends SchemaLike<unknown>, TBodySchema extends SchemaLike<unknown>, TOutputSchema extends SchemaLike<unknown>> = (input: TypedRouteContext<TParamsSchema, TQuerySchema, TBodySchema>) => ([TOutputSchema] extends [ValidationSchema<any>] ? InferSchema<TOutputSchema> : RouteResult) | Promise<[TOutputSchema] extends [ValidationSchema<any>] ? InferSchema<TOutputSchema> : RouteResult>;
1743
+ interface RouteContractOptions<TParamsSchema extends SchemaLike<unknown> = undefined, TQuerySchema extends SchemaLike<unknown> = undefined, TBodySchema extends SchemaLike<unknown> = undefined, TOutputSchema extends SchemaLike<unknown> = undefined> extends RouteOpenApiMetadata {
1744
+ name?: string;
1745
+ middlewares?: MiddlewareHandler[];
1746
+ params?: TParamsSchema;
1747
+ query?: TQuerySchema;
1748
+ body?: TBodySchema;
1749
+ output?: TOutputSchema;
1750
+ bind?: Record<string, BindableModel>;
1751
+ }
1752
+ interface RouteOpenApiMetadata {
1753
+ summary?: string;
1754
+ description?: string;
1755
+ tags?: string[];
1756
+ operationId?: string;
1757
+ deprecated?: boolean;
1758
+ }
1759
+ /**
1760
+ * Represents a registered route definition for introspection.
1761
+ */
1762
+ interface RouteDefinition {
1763
+ /** HTTP method (GET, POST, PUT, PATCH, DELETE) */
1764
+ method: string;
1765
+ /** URL path pattern (e.g., '/users/:id') */
1766
+ path: string;
1767
+ /** Optional route name for URL generation */
1768
+ name?: string;
1769
+ /** Schema metadata attached via RouteContractOptions */
1770
+ schemas?: {
1771
+ params?: SchemaLike<unknown>;
1772
+ query?: SchemaLike<unknown>;
1773
+ body?: SchemaLike<unknown>;
1774
+ output?: SchemaLike<unknown>;
1775
+ };
1776
+ summary?: string;
1777
+ description?: string;
1778
+ tags?: string[];
1779
+ operationId?: string;
1780
+ deprecated?: boolean;
1781
+ }
1782
+ /**
1783
+ * Chainable builder for configuring a registered route.
1784
+ * @template M - Union of registered middleware alias names
1785
+ */
1786
+ interface RouteBuilder<M extends string = never> {
1787
+ /** Set the route name for URL generation. */
1788
+ name(routeName: string): RouteBuilder<M>;
1789
+ /** Attach named middleware to this specific route. */
1790
+ middleware(...names: M[]): RouteBuilder<M>;
1791
+ }
1792
+ interface RouterMountOptions {
1793
+ container?: Container;
1794
+ }
1795
+ /**
1796
+ * Available actions for resource routes.
1797
+ */
1798
+ type ResourceAction = 'index' | 'create' | 'store' | 'show' | 'edit' | 'update' | 'destroy';
1799
+ /**
1800
+ * Options for configuring resource routes.
1801
+ */
1802
+ interface ResourceRouteOptions {
1803
+ name?: string;
1804
+ param?: string;
1805
+ only?: ResourceAction[];
1806
+ except?: ResourceAction[];
1807
+ }
1808
+ /**
1809
+ * Instance-based router for app-local route registration and mounting.
1810
+ * @template M - Union of registered middleware alias names (e.g. `'auth' | 'guest'`)
1811
+ */
1812
+ declare class Router<M extends string = never> {
1813
+ private readonly registry;
1814
+ private readonly prefixStack;
1815
+ private readonly namedRoutes;
1816
+ private readonly middlewareStack;
1817
+ private readonly middlewareAliases;
1818
+ private readonly middlewareGroups;
1819
+ private readonly modelBindings;
1820
+ aliasMiddleware<N extends string>(name: N, handler: MiddlewareHandler): Router<M | N>;
1821
+ groupMiddleware<N extends string>(name: N, middlewareNames: M[]): Router<M | N>;
1822
+ middleware(...names: M[]): RouterMiddlewareGroupBuilder<M>;
1823
+ bind(param: string, modelOrResolver: BindableModel | ModelBindingResolver): this;
1824
+ on<C extends ControllerConstructor>(method: string, path: string, handler: RouteHandler<C>, ...middlewares: MiddlewareHandler[]): RouteBuilder<M>;
1825
+ on<TParamsSchema extends SchemaLike<unknown>, TQuerySchema extends SchemaLike<unknown>, TBodySchema extends SchemaLike<unknown>, TOutputSchema extends SchemaLike<unknown>>(method: string, path: string, options: RouteContractOptions<TParamsSchema, TQuerySchema, TBodySchema, TOutputSchema>, handler: TypedRouteHandler<TParamsSchema, TQuerySchema, TBodySchema, TOutputSchema>): RouteBuilder<M>;
1826
+ on<C extends ControllerConstructor, TParamsSchema extends SchemaLike<unknown>, TQuerySchema extends SchemaLike<unknown>, TBodySchema extends SchemaLike<unknown>, TOutputSchema extends SchemaLike<unknown>>(method: string, path: string, options: RouteContractOptions<TParamsSchema, TQuerySchema, TBodySchema, TOutputSchema>, handler: ControllerAction<C>): RouteBuilder<M>;
1827
+ get<C extends ControllerConstructor>(path: string, handler: RouteHandler<C>, ...middlewares: MiddlewareHandler[]): RouteBuilder<M>;
1828
+ get<TParamsSchema extends SchemaLike<unknown>, TQuerySchema extends SchemaLike<unknown>, TBodySchema extends SchemaLike<unknown>, TOutputSchema extends SchemaLike<unknown>>(path: string, options: RouteContractOptions<TParamsSchema, TQuerySchema, TBodySchema, TOutputSchema>, handler: TypedRouteHandler<TParamsSchema, TQuerySchema, TBodySchema, TOutputSchema>): RouteBuilder<M>;
1829
+ get<C extends ControllerConstructor, TParamsSchema extends SchemaLike<unknown>, TQuerySchema extends SchemaLike<unknown>, TBodySchema extends SchemaLike<unknown>, TOutputSchema extends SchemaLike<unknown>>(path: string, options: RouteContractOptions<TParamsSchema, TQuerySchema, TBodySchema, TOutputSchema>, handler: ControllerAction<C>): RouteBuilder<M>;
1830
+ post<C extends ControllerConstructor>(path: string, handler: RouteHandler<C>, ...middlewares: MiddlewareHandler[]): RouteBuilder<M>;
1831
+ post<TParamsSchema extends SchemaLike<unknown>, TQuerySchema extends SchemaLike<unknown>, TBodySchema extends SchemaLike<unknown>, TOutputSchema extends SchemaLike<unknown>>(path: string, options: RouteContractOptions<TParamsSchema, TQuerySchema, TBodySchema, TOutputSchema>, handler: TypedRouteHandler<TParamsSchema, TQuerySchema, TBodySchema, TOutputSchema>): RouteBuilder<M>;
1832
+ post<C extends ControllerConstructor, TParamsSchema extends SchemaLike<unknown>, TQuerySchema extends SchemaLike<unknown>, TBodySchema extends SchemaLike<unknown>, TOutputSchema extends SchemaLike<unknown>>(path: string, options: RouteContractOptions<TParamsSchema, TQuerySchema, TBodySchema, TOutputSchema>, handler: ControllerAction<C>): RouteBuilder<M>;
1833
+ put<C extends ControllerConstructor>(path: string, handler: RouteHandler<C>, ...middlewares: MiddlewareHandler[]): RouteBuilder<M>;
1834
+ put<TParamsSchema extends SchemaLike<unknown>, TQuerySchema extends SchemaLike<unknown>, TBodySchema extends SchemaLike<unknown>, TOutputSchema extends SchemaLike<unknown>>(path: string, options: RouteContractOptions<TParamsSchema, TQuerySchema, TBodySchema, TOutputSchema>, handler: TypedRouteHandler<TParamsSchema, TQuerySchema, TBodySchema, TOutputSchema>): RouteBuilder<M>;
1835
+ put<C extends ControllerConstructor, TParamsSchema extends SchemaLike<unknown>, TQuerySchema extends SchemaLike<unknown>, TBodySchema extends SchemaLike<unknown>, TOutputSchema extends SchemaLike<unknown>>(path: string, options: RouteContractOptions<TParamsSchema, TQuerySchema, TBodySchema, TOutputSchema>, handler: ControllerAction<C>): RouteBuilder<M>;
1836
+ patch<C extends ControllerConstructor>(path: string, handler: RouteHandler<C>, ...middlewares: MiddlewareHandler[]): RouteBuilder<M>;
1837
+ patch<TParamsSchema extends SchemaLike<unknown>, TQuerySchema extends SchemaLike<unknown>, TBodySchema extends SchemaLike<unknown>, TOutputSchema extends SchemaLike<unknown>>(path: string, options: RouteContractOptions<TParamsSchema, TQuerySchema, TBodySchema, TOutputSchema>, handler: TypedRouteHandler<TParamsSchema, TQuerySchema, TBodySchema, TOutputSchema>): RouteBuilder<M>;
1838
+ patch<C extends ControllerConstructor, TParamsSchema extends SchemaLike<unknown>, TQuerySchema extends SchemaLike<unknown>, TBodySchema extends SchemaLike<unknown>, TOutputSchema extends SchemaLike<unknown>>(path: string, options: RouteContractOptions<TParamsSchema, TQuerySchema, TBodySchema, TOutputSchema>, handler: ControllerAction<C>): RouteBuilder<M>;
1839
+ delete<C extends ControllerConstructor>(path: string, handler: RouteHandler<C>, ...middlewares: MiddlewareHandler[]): RouteBuilder<M>;
1840
+ delete<TParamsSchema extends SchemaLike<unknown>, TQuerySchema extends SchemaLike<unknown>, TBodySchema extends SchemaLike<unknown>, TOutputSchema extends SchemaLike<unknown>>(path: string, options: RouteContractOptions<TParamsSchema, TQuerySchema, TBodySchema, TOutputSchema>, handler: TypedRouteHandler<TParamsSchema, TQuerySchema, TBodySchema, TOutputSchema>): RouteBuilder<M>;
1841
+ delete<C extends ControllerConstructor, TParamsSchema extends SchemaLike<unknown>, TQuerySchema extends SchemaLike<unknown>, TBodySchema extends SchemaLike<unknown>, TOutputSchema extends SchemaLike<unknown>>(path: string, options: RouteContractOptions<TParamsSchema, TQuerySchema, TBodySchema, TOutputSchema>, handler: ControllerAction<C>): RouteBuilder<M>;
1842
+ group(prefix: string, callback: (router: Router<M>) => void): this;
1843
+ route(name: string, params?: Record<string, string | number>): string;
1844
+ hasRoute(name: string): boolean;
1845
+ resource<C extends ControllerConstructor>(path: string, controller: C, options?: ResourceRouteOptions): this;
1846
+ mount(app: Hono, options?: RouterMountOptions): void;
1847
+ clear(): void;
1848
+ resetMiddleware(): void;
1849
+ definitions(): RouteDefinition[];
1850
+ applyMiddlewareScope<T>(names: string[], callback: () => T): T;
1851
+ private register;
1852
+ private add;
1853
+ private resolveMiddlewareNames;
1854
+ }
1855
+ declare class RouterMiddlewareGroupBuilder<M extends string = never> {
1856
+ private readonly router;
1857
+ private readonly names;
1858
+ constructor(router: Router<M>, names: string[]);
1859
+ group(callback: (router: Router<M>) => void): Router<M>;
1860
+ get<C extends ControllerConstructor>(path: string, handler: RouteHandler<C>, ...middlewares: MiddlewareHandler[]): RouteBuilder<M>;
1861
+ get<TParamsSchema extends SchemaLike<unknown>, TQuerySchema extends SchemaLike<unknown>, TBodySchema extends SchemaLike<unknown>, TOutputSchema extends SchemaLike<unknown>>(path: string, options: RouteContractOptions<TParamsSchema, TQuerySchema, TBodySchema, TOutputSchema>, handler: TypedRouteHandler<TParamsSchema, TQuerySchema, TBodySchema, TOutputSchema>): RouteBuilder<M>;
1862
+ post<C extends ControllerConstructor>(path: string, handler: RouteHandler<C>, ...middlewares: MiddlewareHandler[]): RouteBuilder<M>;
1863
+ post<TParamsSchema extends SchemaLike<unknown>, TQuerySchema extends SchemaLike<unknown>, TBodySchema extends SchemaLike<unknown>, TOutputSchema extends SchemaLike<unknown>>(path: string, options: RouteContractOptions<TParamsSchema, TQuerySchema, TBodySchema, TOutputSchema>, handler: TypedRouteHandler<TParamsSchema, TQuerySchema, TBodySchema, TOutputSchema>): RouteBuilder<M>;
1864
+ put<C extends ControllerConstructor>(path: string, handler: RouteHandler<C>, ...middlewares: MiddlewareHandler[]): RouteBuilder<M>;
1865
+ put<TParamsSchema extends SchemaLike<unknown>, TQuerySchema extends SchemaLike<unknown>, TBodySchema extends SchemaLike<unknown>, TOutputSchema extends SchemaLike<unknown>>(path: string, options: RouteContractOptions<TParamsSchema, TQuerySchema, TBodySchema, TOutputSchema>, handler: TypedRouteHandler<TParamsSchema, TQuerySchema, TBodySchema, TOutputSchema>): RouteBuilder<M>;
1866
+ patch<C extends ControllerConstructor>(path: string, handler: RouteHandler<C>, ...middlewares: MiddlewareHandler[]): RouteBuilder<M>;
1867
+ patch<TParamsSchema extends SchemaLike<unknown>, TQuerySchema extends SchemaLike<unknown>, TBodySchema extends SchemaLike<unknown>, TOutputSchema extends SchemaLike<unknown>>(path: string, options: RouteContractOptions<TParamsSchema, TQuerySchema, TBodySchema, TOutputSchema>, handler: TypedRouteHandler<TParamsSchema, TQuerySchema, TBodySchema, TOutputSchema>): RouteBuilder<M>;
1868
+ delete<C extends ControllerConstructor>(path: string, handler: RouteHandler<C>, ...middlewares: MiddlewareHandler[]): RouteBuilder<M>;
1869
+ delete<TParamsSchema extends SchemaLike<unknown>, TQuerySchema extends SchemaLike<unknown>, TBodySchema extends SchemaLike<unknown>, TOutputSchema extends SchemaLike<unknown>>(path: string, options: RouteContractOptions<TParamsSchema, TQuerySchema, TBodySchema, TOutputSchema>, handler: TypedRouteHandler<TParamsSchema, TQuerySchema, TBodySchema, TOutputSchema>): RouteBuilder<M>;
1870
+ }
1871
+
1872
+ /**
1873
+ * Base service provider class.
1874
+ *
1875
+ * Service providers are the central place of all application bootstrapping.
1876
+ * Your own application, as well as all core services, are bootstrapped via providers.
1877
+ *
1878
+ * @example
1879
+ * ```typescript
1880
+ * export class AppServiceProvider extends ServiceProvider {
1881
+ * register(): void {
1882
+ * // Register bindings
1883
+ * this.container.singleton('db', (c) => new Database(c.make('config')))
1884
+ * }
1885
+ *
1886
+ * boot(): void {
1887
+ * // Bootstrap after all providers registered
1888
+ * const db = this.container.make<Database>('db')
1889
+ * db.connect()
1890
+ * }
1891
+ * }
1892
+ * ```
1893
+ */
1894
+ declare abstract class ServiceProvider implements Provider {
1895
+ protected container: Container;
1896
+ /**
1897
+ * Whether this provider should be deferred.
1898
+ * Deferred providers are only loaded when one of their provided services is requested.
1899
+ */
1900
+ static deferred: boolean;
1901
+ /**
1902
+ * The services provided by this provider (for deferred loading).
1903
+ */
1904
+ static provides: string[];
1905
+ constructor(container: Container);
1906
+ /**
1907
+ * Register any application services.
1908
+ * This is called before any other providers have booted.
1909
+ */
1910
+ abstract register(): void | Promise<void>;
1911
+ /**
1912
+ * Bootstrap any application services.
1913
+ * This is called after all providers have registered.
1914
+ */
1915
+ boot?(): void | Promise<void>;
1916
+ /**
1917
+ * Get the services provided by the provider.
1918
+ */
1919
+ provides(): string[];
1920
+ /**
1921
+ * Check if this provider is deferred.
1922
+ */
1923
+ isDeferred(): boolean;
1924
+ }
1925
+ /**
1926
+ * Provider manager for registering and booting providers.
1927
+ */
1928
+ declare class ProviderManager {
1929
+ protected container: Container;
1930
+ protected providers: ServiceProvider[];
1931
+ protected registered: Set<ServiceProvider>;
1932
+ protected booted: Set<ServiceProvider>;
1933
+ protected deferredProviders: Map<string, ServiceProvider>;
1934
+ private allBooted;
1935
+ constructor(container: Container);
1936
+ /**
1937
+ * Register a provider.
1938
+ */
1939
+ register(providerOrClass: ServiceProvider | (new (container: Container) => ServiceProvider)): this;
1940
+ /**
1941
+ * Register multiple providers.
1942
+ */
1943
+ registerMany(providers: Array<ServiceProvider | (new (container: Container) => ServiceProvider)>): this;
1944
+ /**
1945
+ * Register all non-deferred providers.
1946
+ */
1947
+ registerAll(): Promise<void>;
1948
+ /**
1949
+ * Boot all registered providers.
1950
+ */
1951
+ bootAll(): Promise<void>;
1952
+ /**
1953
+ * Load a deferred provider for a service.
1954
+ */
1955
+ loadDeferredProvider(service: string): Promise<void>;
1956
+ /**
1957
+ * Check if a service is provided by a deferred provider.
1958
+ */
1959
+ isDeferredService(service: string): boolean;
1960
+ /**
1961
+ * Get all registered providers.
1962
+ */
1963
+ getProviders(): ServiceProvider[];
1964
+ /**
1965
+ * Get all deferred services.
1966
+ */
1967
+ getDeferredServices(): string[];
1968
+ }
1969
+
1970
+ declare const GUREN_ASCII_ART: string;
1971
+ interface DevBannerOptions {
1972
+ hostname: string;
1973
+ port: number;
1974
+ assetsUrl?: string;
1975
+ }
1976
+ declare function logDevServerBanner({ hostname, port, assetsUrl, }: DevBannerOptions): void;
1977
+
1978
+ interface StartViteDevServerOptions {
1979
+ root?: string;
1980
+ config?: InlineConfig;
1981
+ host?: boolean | string;
1982
+ port?: number;
1983
+ }
1984
+ interface StartedViteDevServer {
1985
+ server: ViteDevServer;
1986
+ localUrl: string;
1987
+ networkUrls: string[];
1988
+ }
1989
+ declare function startViteDevServer(options?: StartViteDevServerOptions): Promise<StartedViteDevServer>;
1990
+
1991
+ type BootCallback = (app: Hono) => void | Promise<void>;
1992
+ /**
1993
+ * Service provider class constructor type.
1994
+ */
1995
+ type ServiceProviderConstructor = new (container: Container) => ServiceProvider;
1996
+ type RouteRegistration = (router: Router) => void | Promise<void>;
1997
+ type ApplicationFeatures = Record<string, unknown>;
1998
+ interface ApplicationOptions {
1999
+ readonly boot?: BootCallback;
2000
+ readonly providers?: Array<ServiceProviderConstructor>;
2001
+ readonly auth?: AuthPluginOptions;
2002
+ readonly discover?: boolean;
2003
+ readonly routes?: RouteRegistration;
2004
+ readonly features?: ApplicationFeatures;
2005
+ /**
2006
+ * Configure or disable the default security headers middleware.
2007
+ * Set to `false` to disable entirely, or pass `SecurityHeadersOptions` to customize.
2008
+ * Enabled by default with safe Rails-matching defaults.
2009
+ */
2010
+ readonly securityHeaders?: SecurityHeadersOptions | false;
2011
+ /**
2012
+ * Configure host authorization middleware for DNS rebinding protection.
2013
+ * Pass `HostAuthorizationOptions` to enable, or `false` / omit to disable.
2014
+ * The `create-app` template includes a default localhost configuration.
2015
+ */
2016
+ readonly hostAuthorization?: HostAuthorizationOptions | false;
2017
+ }
2018
+ interface AuthPluginOptions {
2019
+ autoSession?: boolean;
2020
+ sessionOptions?: CreateSessionMiddlewareOptions;
2021
+ /**
2022
+ * Automatically register CSRF middleware when session is enabled.
2023
+ * Defaults to `true`. Set to `false` to disable (e.g., for pure API servers).
2024
+ */
2025
+ autoCsrf?: boolean;
2026
+ /**
2027
+ * Options passed to the CSRF middleware when `autoCsrf` is enabled.
2028
+ */
2029
+ csrfOptions?: CsrfOptions;
2030
+ }
2031
+ interface ApplicationListenOptions {
2032
+ port?: number;
2033
+ hostname?: string;
2034
+ assetsUrl?: string;
2035
+ vite?: StartViteDevServerOptions | false;
2036
+ }
2037
+ /**
2038
+ * Application wires an app-local router into a running Hono instance.
2039
+ *
2040
+ * It embeds a DI Container as the backbone of the framework, binding core
2041
+ * services and managing providers through the container's ProviderManager.
2042
+ */
2043
+ declare class Application {
2044
+ private readonly options;
2045
+ readonly hono: Hono;
2046
+ readonly container: Container;
2047
+ readonly router: Router;
2048
+ private readonly providerManager;
2049
+ private readonly authManager;
2050
+ private viteDevServer?;
2051
+ private bunServer?;
2052
+ private viteTeardownRegistered;
2053
+ private bunTeardownRegistered;
2054
+ private autoSessionAttached;
2055
+ private routesRegistered;
2056
+ constructor(options?: ApplicationOptions);
2057
+ get auth(): AuthManager;
2058
+ get authOptions(): AuthPluginOptions | undefined;
2059
+ markAutoSessionAttached(): void;
2060
+ hasAutoSessionAttached(): boolean;
2061
+ /**
2062
+ * Mounts the application router onto the Hono instance.
2063
+ */
2064
+ mountRoutes(): Promise<void>;
2065
+ /**
2066
+ * Allows registering global middlewares directly on the underlying Hono app.
2067
+ */
2068
+ use(path: string, ...middleware: MiddlewareHandler[]): void;
2069
+ /**
2070
+ * Executes provider registration, boot callback, mounts routes, and boots providers.
2071
+ */
2072
+ boot(): Promise<void>;
2073
+ /**
2074
+ * Registers default security middleware (headers + host authorization).
2075
+ */
2076
+ private mountSecurityDefaults;
2077
+ private mountHostAuthorization;
2078
+ /**
2079
+ * Mounts the MCP endpoint at /_guren/mcp when explicitly enabled.
2080
+ * Requires GUREN_MCP=1 environment variable. Never active in production.
2081
+ * This allows AI coding agents to introspect the project.
2082
+ */
2083
+ private mountMcpEndpoint;
2084
+ /**
2085
+ * Fetch handler to integrate with Bun.serve or any standard Fetch runtime.
2086
+ */
2087
+ fetch(request: Request, env?: unknown, executionCtx?: ExecutionContext): Promise<Response>;
2088
+ /**
2089
+ * Convenience helper to start a Bun server when available.
2090
+ */
2091
+ listen(options?: ApplicationListenOptions): Promise<void>;
2092
+ /**
2093
+ * Register a service provider.
2094
+ */
2095
+ register(provider: ServiceProviderConstructor): this;
2096
+ /**
2097
+ * Register multiple service providers.
2098
+ */
2099
+ registerMany(providers: Array<ServiceProviderConstructor>): this;
2100
+ /**
2101
+ * Logs the rich development server banner to the console.
2102
+ */
2103
+ logDevServerBanner(options: DevBannerOptions): void;
2104
+ private closeViteDevServer;
2105
+ private registerViteTeardown;
2106
+ private registerBunTeardown;
2107
+ }
2108
+ declare function createApp(options?: ApplicationOptions): Application;
2109
+
2110
+ export { type NotificationChannelFactory as $, Application as A, type InertiaSharedProps as B, Container as C, type DevBannerOptions as D, type ErrorResponse as E, type FailedJob as F, GUREN_ASCII_ART as G, type HostAuthorizationOptions as H, type InertiaOptions as I, type InertiaSsrContext as J, type InertiaSsrOptions as K, type InertiaSsrRenderer as L, type InertiaSsrResult as M, NotificationManager as N, type InferInertiaProps as O, type Provider as P, QueueManager as Q, Job as R, ServiceProvider as S, type JobClass as T, type JobFailureHandler as U, type JobHandler as V, type JobOptions as W, type Notifiable as X, Notification as Y, type NotificationAttachment as Z, type NotificationChannel as _, type StartViteDevServerOptions as a, setQueueDriver as a$, type NotificationClass as a0, type NotificationMailMessage as a1, type NotificationManagerOptions as a2, ProviderManager as a3, type QueueConfig as a4, type QueueDriver as a5, type QueueDriverFactory as a6, type QueuedJob as a7, type RendererRegistration as a8, type ResolvedSharedInertiaProps as a9, clearJobRegistry as aA, createApp as aB, createContainer as aC, createCsrfMiddleware as aD, createExceptionHandler as aE, createHostAuthorizationMiddleware as aF, createNotificationManager as aG, createQueueManager as aH, createSecurityHeaders as aI, csrfField as aJ, formatValidationErrors as aK, getContainer as aL, getCsrfToken as aM, getExceptionHandler as aN, getJob as aO, getNotificationManager as aP, getQueueDriver as aQ, getRegisteredJobs as aR, getValidatedData as aS, inertia as aT, parseRequestPayload as aU, registerJob as aV, resolve as aW, setContainer as aX, setExceptionHandler as aY, setInertiaSharedProps as aZ, setNotificationManager as a_, type ResourceRouteOptions as aa, type RouteBuilder as ab, type RouteContractOptions as ac, type RouteDefinition as ad, type RouteOpenApiMetadata as ae, type ResourceAction as af, Router as ag, type SecurityHeadersOptions as ah, type SentNotification as ai, type ServiceBinding as aj, type ServiceClass as ak, type ServiceFactory as al, type ServiceProviderClass as am, type ServiceProviderConstructor as an, type ServiceProviderOptions as ao, type SharedInertiaPropsResolver as ap, type SlackAttachment as aq, type SlackBlock as ar, type SlackMessage as as, VALIDATED_DATA_KEY as at, type ValidateRequestOptions as au, type ValidationSchema as av, type WorkerOptions as aw, abort as ax, abortIf as ay, abortUnless as az, type StartedViteDevServer as b, validate as b0, validateRequest as b1, validateRequestWith as b2, validateSafe as b3, verifyCsrfToken as b4, type ServiceBindings as c, type ApplicationListenOptions as d, type AuthPayload as e, CSRF_FORM_FIELD as f, CSRF_HEADER_NAME as g, CSRF_TOKEN_KEY as h, type ContextualBinding as i, type ContextualBindingBuilder as j, type ContextualNeedsBuilder as k, logDevServerBanner as l, Controller as m, type ControllerInertiaProps as n, type CsrfOptions as o, type DatabaseChannelOptions as p, type DatabaseNotification as q, type ExceptionClass as r, startViteDevServer as s, ExceptionHandler as t, type ExceptionHandlerOptions as u, type ExceptionRenderer as v, type ExceptionReporter as w, type HstsOptions as x, type InertiaPagePayload as y, type InertiaResponse as z };