@orieljs/framework 0.1.0-alpha.6 → 0.1.0-alpha.8

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 (86) hide show
  1. package/NOTICE +4 -0
  2. package/README.md +10 -1
  3. package/TRADEMARKS.md +33 -0
  4. package/dist/{chunk-POEP4B2M.js → chunk-7ZQZYDOC.js} +745 -105
  5. package/dist/chunk-7ZQZYDOC.js.map +1 -0
  6. package/dist/{chunk-I63ZFMX6.js → chunk-GVNLZZTN.js} +1 -1
  7. package/dist/chunk-GVNLZZTN.js.map +1 -0
  8. package/dist/{chunk-ZOEPKBVF.js → chunk-SPQUX3C7.js} +1347 -428
  9. package/dist/chunk-SPQUX3C7.js.map +1 -0
  10. package/dist/{chunk-MFTZQMZM.js → chunk-VOYW3R5J.js} +4 -4
  11. package/dist/chunk-VOYW3R5J.js.map +1 -0
  12. package/dist/contracts.d.ts +515 -17
  13. package/dist/contracts.js +1 -1
  14. package/dist/index.d-WQpfdIbG.d.ts +630 -0
  15. package/dist/index.d.ts +964 -152
  16. package/dist/index.js +4279 -866
  17. package/dist/index.js.map +1 -1
  18. package/dist/{jsx-runtime-CBZQYYDS.d.ts → jsx-runtime-6um4Mwfb.d.ts} +96 -5
  19. package/dist/jsx-runtime.d.ts +2 -2
  20. package/dist/jsx-runtime.js +3 -3
  21. package/dist/{testing-BM481Hdz.d.ts → testing-CKwfWJGn.d.ts} +180 -15
  22. package/dist/testing.d.ts +2 -2
  23. package/dist/testing.js +3 -3
  24. package/docs/authentication.md +487 -0
  25. package/docs/authorization.md +435 -0
  26. package/docs/cache.md +647 -0
  27. package/docs/collections.md +2270 -0
  28. package/docs/configuration.md +334 -0
  29. package/docs/console.md +651 -0
  30. package/docs/container.md +430 -0
  31. package/docs/controllers.md +406 -0
  32. package/docs/csrf.md +126 -0
  33. package/docs/database-testing.md +144 -0
  34. package/docs/database.md +236 -0
  35. package/docs/deployment.md +276 -0
  36. package/docs/eloquent-collections.md +218 -0
  37. package/docs/eloquent-factories.md +255 -0
  38. package/docs/eloquent-mutators.md +254 -0
  39. package/docs/eloquent-observers.md +145 -0
  40. package/docs/eloquent-relationships.md +557 -0
  41. package/docs/eloquent.md +494 -0
  42. package/docs/encryption.md +104 -0
  43. package/docs/errors.md +318 -0
  44. package/docs/events.md +336 -0
  45. package/docs/facades.md +278 -0
  46. package/docs/hashing.md +118 -0
  47. package/docs/helpers.md +1281 -0
  48. package/docs/http-tests.md +386 -0
  49. package/docs/inertia.md +485 -0
  50. package/docs/installation.md +209 -0
  51. package/docs/lifecycle.md +234 -0
  52. package/docs/live-tests.md +226 -0
  53. package/docs/live.md +910 -0
  54. package/docs/logging.md +255 -0
  55. package/docs/mail.md +619 -0
  56. package/docs/middleware.md +384 -0
  57. package/docs/migrations.md +416 -0
  58. package/docs/mocking.md +264 -0
  59. package/docs/navigation.json +273 -0
  60. package/docs/notifications.md +225 -0
  61. package/docs/pagination.md +247 -0
  62. package/docs/passwords.md +207 -0
  63. package/docs/providers.md +187 -0
  64. package/docs/queries.md +600 -0
  65. package/docs/queues.md +330 -0
  66. package/docs/requests.md +533 -0
  67. package/docs/responses.md +444 -0
  68. package/docs/routing.md +738 -0
  69. package/docs/scheduling.md +277 -0
  70. package/docs/seeding.md +122 -0
  71. package/docs/session.md +409 -0
  72. package/docs/starter-kits.md +396 -0
  73. package/docs/storage.md +192 -0
  74. package/docs/structure.md +264 -0
  75. package/docs/testing.md +165 -0
  76. package/docs/time-travel.md +138 -0
  77. package/docs/validation.md +1792 -0
  78. package/docs/verification.md +152 -0
  79. package/docs/views.md +566 -0
  80. package/docs/vite.md +322 -0
  81. package/package.json +34 -32
  82. package/dist/chunk-I63ZFMX6.js.map +0 -1
  83. package/dist/chunk-MFTZQMZM.js.map +0 -1
  84. package/dist/chunk-POEP4B2M.js.map +0 -1
  85. package/dist/chunk-ZOEPKBVF.js.map +0 -1
  86. package/dist/index.d-BJyJx6U1.d.ts +0 -319
package/dist/index.d.ts CHANGED
@@ -1,17 +1,17 @@
1
- import { Container as Container$1, Factory as Factory$1, Abstract, Concrete, OrielError, ConfigRepository, Application as Application$2, ServiceProvider, ServiceProviderClass, MiddlewareConfigurator, ExceptionsConfigurator, HttpKernel, Htmlable, Notifiable as Notifiable$1, Notification as Notification$2, NotificationChannel, MailRecipient, NotificationDispatcher, Job, BusDispatcher, EventDispatcher, MailManager as MailManager$1, QueueManager as QueueManager$1, FilesystemManager as FilesystemManager$1, Pipeline, Class, PipeClosure, Pipe, PipelineFactory, Router, ControllerAction, RouteClosure, InvokableClass, Route as Route$1, RouteAction, MiddlewareReference, ResourceOptions, RouteRegistrar, MiddlewareClass, HttpRequest, UrlGenerator, ModelNotFoundError as ModelNotFoundError$1, Middleware, Next as Next$1, ExceptionHandler, UploadedFile, RedirectResponse, HeadersInit, Redirector, ResponseFactory as ResponseFactory$1, BodyInit, Session, Rules, RouteName, CookieJar as CookieJar$1, ConsoleKernel, CommandContext, OptionValue, ClosureCommand as ClosureCommand$1, Command as Command$1, Schedule as Schedule$1, ScheduledEvent, Row, ModelInstance, QueryBuilder, DatabaseConnection, DriverName, Operator, DatabaseManager, DatabaseNotification as DatabaseNotification$1, RouteModelResolver, Token, ValidationRule, MessageBag, ValidationError, ValidationFactory, Validator as Validator$1, RuleCallback, Encrypter as Encrypter$1, Hasher, Cookie as Cookie$1, SessionHandler, Gate as Gate$1, Authenticatable, AbilityCallback, Credentials, AuthFactory, StatefulGuard, Guard, UserProvider, ModelStatic, AuthenticationError as AuthenticationError$1, PasswordBroker as PasswordBroker$1, PasswordStatus, MustVerifyEmail, Logger, LogLevel, ErrorKind, LogManager as LogManager$1, ListenerClass, Listener as Listener$1, ClassRegistry, CacheManager as CacheManager$1, CacheRepository, Lock, RateLimiter as RateLimiter$1, Filesystem, PutOptions, QueueJob, QueuePayload, Batch as Batch$1, BatchRepository, PendingBatchOptions, FailedJobProvider, FailedJob, Queue as Queue$1, PendingChain as PendingChain$1, PendingBatch as PendingBatch$1, ShouldQueue, MailTransport, OutgoingMessage, SentMessage, Mailer, Address, Mailable as Mailable$1, PendingMail, Attachment, Envelope, Content, PropCallback, InertiaFactory, InertiaResponse, InertiaPage, InertiaScrollProp, InertiaOnceProp, InertiaSsrGateway, InertiaSsrResponse } from './contracts.js';
2
- export { RouteList } from './contracts.js';
3
- import { F as Facade, S as ServiceProvider$1, f as fileType, a as Stringable, C as Collection, L as LazyCollection } from './index.d-BJyJx6U1.js';
4
- export { A as Arr, b as ClassRegistry, c as FacadeStatics, d as Str, _ as __, e as app, g as collect, h as config, i as facade, n as now, r as retry, t as tap, v as value } from './index.d-BJyJx6U1.js';
5
- import { B as BusFake, E as EventFake, M as MailFake, N as NotificationFake, Q as QueueFake, S as StorageFake } from './testing-BM481Hdz.js';
6
- export { C as Component, a as ComponentResult, b as Computed, c as CorruptComponentPayloadError, d as ErrorBag, I as InvalidLiveRequestError, L as Live, e as LiveComponentManager, f as LiveComponentNotFoundError, g as LiveError, h as LiveProps, i as LiveServiceProvider, j as Locked, k as MethodNotCallableError, O as On, P as PERSISTENT_MIDDLEWARE, l as Paginated, m as Pagination, n as PaginationProps, o as PaginationSource, p as PendingEvent, q as PersistentMiddleware, r as PropertyNotUpdatableError, T as TestRequestScope, s as Testable, U as UPDATE_URI, W as WithPagination, t as componentName, u as live, v as persistentMiddleware } from './testing-BM481Hdz.js';
1
+ import { Container as Container$1, Factory as Factory$1, Abstract, Concrete, OrielError, ConfigRepository, Application as Application$2, ServiceProvider, ServiceProviderClass, MiddlewareConfigurator, ExceptionsConfigurator, HttpKernel, Htmlable, Notifiable as Notifiable$1, Notification as Notification$2, NotificationChannel, MailRecipient, Attachment, NotificationDispatcher, Job, BusDispatcher, EventDispatcher, MailManager as MailManager$1, QueueManager as QueueManager$1, FilesystemManager as FilesystemManager$1, Pipeline, Class, PipeClosure, Pipe, PipelineFactory, Router, ControllerAction, RouteClosure, InvokableClass, Route as Route$1, RouteAction, MiddlewareReference, ResourceOptions, RouteRegistrar, MiddlewareClass, HttpRequest, UrlGenerator, ModelNotFoundError as ModelNotFoundError$1, Middleware, Next as Next$1, ExceptionHandler, UploadedFile, RedirectResponse, HeadersInit, MessageBag, Redirector, ResponseFactory as ResponseFactory$1, BodyInit, Session, Rules, InferValidatedType, RouteName, RouteArguments, CookieJar as CookieJar$1, ConsoleKernel, CommandContext, OptionValue, ClosureCommand as ClosureCommand$1, Command as Command$1, Schedule as Schedule$1, ScheduledEvent, ScheduleHook, Row, ModelInstance, QueryBuilder, DatabaseConnection, DriverName, Operator, DatabaseManager, DatabaseNotification as DatabaseNotification$1, RouteModelResolver, Token, RuleTyping, TypedValidationRule, ValidationRule, InValue, ValidationError, ValidationFactory, Validator as Validator$1, RuleCallback, Encrypter as Encrypter$1, Hasher, Cookie as Cookie$1, SessionHandler, Gate as Gate$1, Authenticatable, AbilityCallback, Credentials, AuthFactory, StatefulGuard, Guard, UserProvider, ModelStatic, AuthenticationError as AuthenticationError$1, PasswordBroker as PasswordBroker$1, PasswordStatus, MustVerifyEmail, Logger, LogLevel, ErrorKind, LogManager as LogManager$1, ListenerClass, Listener as Listener$1, ClassRegistry, CacheManager as CacheManager$1, CacheRepository, Lock, RateLimiter as RateLimiter$1, Filesystem, PutOptions, QueueJob, QueuePayload, Batch as Batch$1, BatchRepository, PendingBatchOptions, FailedJobProvider, FailedJob, Queue as Queue$1, PendingChain as PendingChain$1, PendingBatch as PendingBatch$1, ShouldQueue, MailTransport, OutgoingMessage, SentMessage, Mailer, Address, Mailable as Mailable$1, PendingMail, Envelope, Content, PropCallback, InertiaFactory, InertiaResponse, InertiaPage, InertiaScrollProp, InertiaOnceProp, InertiaSsrGateway, InertiaSsrResponse } from './contracts.js';
2
+ export { InferRuleType, RouteList, RouteParameter, RouteParameters } from './contracts.js';
3
+ import { F as Facade, S as ServiceProvider$1, f as fileType, a as Stringable, C as Collection, L as LazyCollection, O as Operator$1 } from './index.d-WQpfdIbG.js';
4
+ export { A as Arr, b as ClassRegistry, c as FacadeStatics, I as ItemNotFoundError, M as MultipleItemsFoundError, d as Str, _ as __, e as app, g as collect, h as config, i as facade, n as now, r as retry, t as tap, v as value } from './index.d-WQpfdIbG.js';
5
+ import { B as BusFake, E as EventFake, M as MailFake, N as NotificationFake, Q as QueueFake, S as StorageFake } from './testing-CKwfWJGn.js';
6
+ export { C as Component, a as ComponentResult, b as Computed, c as CorruptComponentPayloadError, d as ErrorBag, F as FileNotPreviewableError, I as InvalidLiveRequestError, e as InvalidUploadSignatureError, L as Live, f as LiveComponentManager, g as LiveComponentNotFoundError, h as LiveError, i as LiveProps, j as LiveServiceProvider, k as Locked, l as MethodNotCallableError, O as On, P as PERSISTENT_MIDDLEWARE, m as PREVIEW_URI, n as Paginated, o as Pagination, p as PaginationProps, q as PaginationSource, r as PendingEvent, s as PersistentMiddleware, t as PropertyNotUpdatableError, T as TEMPORARY_UPLOAD_DEFAULTS, u as TemporaryFileData, v as TemporaryFileNotFoundError, w as TemporaryUploadedFile, x as TestRequestScope, y as Testable, U as UPDATE_URI, z as UPLOAD_URI, A as UploadValidationError, W as WithFileUploads, D as WithPagination, G as componentName, H as live, J as persistentMiddleware } from './testing-CKwfWJGn.js';
7
7
  import { IncomingMessage, ServerResponse } from 'node:http';
8
+ import { SpawnOptions, ChildProcess } from 'node:child_process';
8
9
  import { Kysely, RawBuilder, CompiledQuery, QueryResult, SqliteDatabase, SqliteStatement, Dialect } from 'kysely';
9
10
  import Redis$1, { Redis } from 'ioredis';
10
11
  import pino from 'pino';
11
12
  import { WriteStream } from 'node:fs';
12
13
  import { Writable } from 'node:stream';
13
- import { SpawnOptions, ChildProcess } from 'node:child_process';
14
- export { C as ClassValue, E as ELEMENT, F as FileViewFinder, a as Fragment, H as HtmlAttributes, b as HtmlString, I as InvalidViewError, O as OrielElement, P as Props, R as Renderable, S as StyleObject, T as TsxView, V as View, c as ViewComponent, d as ViewEnvironment, e as ViewFactoryImpl, f as ViewNotFoundError, g as ViewRenderError, h as ViewServiceProvider, i as classNames, j as createElement, k as csrfField, l as e, m as isElement, n as isHtmlable, o as methodField, r as raw, p as renderToStream, q as renderToString, s as styleString, v as view } from './jsx-runtime-CBZQYYDS.js';
14
+ export { C as ClassValue, E as ELEMENT, F as FileViewFinder, a as Fragment, H as HtmlAttributes, b as HtmlString, I as InvalidViewError, L as LiveDirectives, c as LiveEvent, O as OrielElement, P as Props, R as Renderable, S as StyleObject, T as TsxView, V as View, d as ViewComponent, e as ViewEnvironment, f as ViewFactoryImpl, g as ViewNotFoundError, h as ViewRenderError, i as ViewServiceProvider, j as classNames, k as createElement, l as csrfField, m as e, n as isElement, o as isHtmlable, p as methodField, r as raw, q as renderToStream, s as renderToString, t as styleString, v as view } from './jsx-runtime-6um4Mwfb.js';
15
15
 
16
16
  type Key = unknown;
17
17
  type Lifetime = 'transient' | 'singleton' | 'scoped';
@@ -71,6 +71,23 @@ declare class ContainerNotAvailableError extends Error implements OrielError {
71
71
  declare function currentContainer(): Container$1 | undefined;
72
72
  declare function inject<T>(abstract: Abstract<T>): T;
73
73
 
74
+ /**
75
+ * Laravel's Config facade: the bound ConfigRepository (`get`, `set`, `has`, `push`, `all`), with Laravel 12's
76
+ * `prepend()`, `getMany()` and typed getters (`string()`, `integer()`, `float()`, `boolean()`, `array()`). A float is
77
+ * any number (JavaScript has one number type); an array is a list or an object (a config section).
78
+ */
79
+ declare const Config: Facade<ConfigRepository, {
80
+ /** Several keys at once: a list of keys, or an object of keys and their defaults. */
81
+ getMany(this: ConfigRepository, keys: readonly string[] | Readonly<Record<string, unknown>>): Record<string, unknown>;
82
+ /** Puts a value first in the array at `key` (creating it when missing). */
83
+ prepend(this: ConfigRepository, key: string, value: unknown): void;
84
+ string(this: ConfigRepository, key: string, defaultValue?: string): string;
85
+ integer(this: ConfigRepository, key: string, defaultValue?: number): number;
86
+ float(this: ConfigRepository, key: string, defaultValue?: number): number;
87
+ boolean(this: ConfigRepository, key: string, defaultValue?: boolean): boolean;
88
+ array(this: ConfigRepository, key: string, defaultValue?: unknown[] | Record<string, unknown>): unknown[] | Record<string, unknown>;
89
+ }>;
90
+
74
91
  declare class Repository$1 implements ConfigRepository {
75
92
  private readonly items;
76
93
  constructor(items?: Record<string, unknown>);
@@ -113,11 +130,13 @@ declare class ApplicationBuilder {
113
130
  type LifecycleCallback = (app: Application$2) => void | Promise<void>;
114
131
  declare class Application$1 extends Container implements Application$2 {
115
132
  private readonly base;
116
- readonly version = "0.1.0-alpha.6";
133
+ readonly version = "0.1.0-alpha.8";
117
134
  private readonly providers;
118
135
  private readonly bootingCallbacks;
119
136
  private readonly bootedCallbacks;
120
137
  private readonly terminatingCallbacks;
138
+ private readonly shutdownCallbacks;
139
+ private shutdownPromise;
121
140
  private bootPromise;
122
141
  private hasBooted;
123
142
  private inConsole;
@@ -151,6 +170,20 @@ declare class Application$1 extends Container implements Application$2 {
151
170
  terminating(callback: () => void | Promise<void>): void;
152
171
  handle(request: Request): Promise<Response>;
153
172
  terminate(): Promise<void>;
173
+ /**
174
+ * A callback for the end of the process (the CLI after its command, the server on SIGTERM): close DB pools, Redis
175
+ * clients and log files. Not in Laravel, whose PHP processes end with each request.
176
+ */
177
+ onShutdown(callback: () => void | Promise<void>): void;
178
+ /**
179
+ * Runs the shutdown callbacks once (a second call returns the same promise), newest first: an app's own callbacks
180
+ * run before the framework closes what they use, then the framework's in the reverse of its providers' order (the
181
+ * queue, database and cache connections close, then the log is written, then the session store closes). A failing
182
+ * callback is printed with console.error (the log may be closed already) and the others still run; after 10 seconds
183
+ * the rest are given up on, so the process can still exit. Never rejects.
184
+ */
185
+ shutdown(): Promise<void>;
186
+ private runShutdown;
154
187
  private runBoot;
155
188
  private bootProvider;
156
189
  }
@@ -313,16 +346,40 @@ declare class NotificationDispatcherUnavailableError extends Error implements Or
313
346
  constructor();
314
347
  }
315
348
 
349
+ /*!
350
+ * Laravel's default notification mail (the `notifications::email` view in the `mail::` markdown components with the
351
+ * `default` theme), as Laravel 12 sends it: the same HTML, with the theme's CSS inlined as CssToInlineStyles inlines
352
+ * it, and the same plain-text part. The lines are plain text (escaped), not Markdown.
353
+ *
354
+ * laravel/framework: Copyright (c) Taylor Otwell
355
+ *
356
+ * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated
357
+ * documentation files (the "Software"), to deal in the Software without restriction, including without limitation the
358
+ * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to
359
+ * permit persons to whom the Software is furnished to do so, subject to the following conditions:
360
+ *
361
+ * The above copyright notice and this permission notice shall be included in all copies or substantial portions of the
362
+ * Software.
363
+ *
364
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
365
+ * WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
366
+ * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
367
+ * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
368
+ */
369
+ type MailLevel = 'info' | 'success' | 'error';
370
+
316
371
  interface MailMessageAction {
317
372
  text: string;
318
373
  url: string;
319
374
  }
320
375
  /**
321
- * Laravel's Illuminate\Notifications\Messages\MailMessage: greeting/line/action/salutation, rendered to a default
322
- * HTML+text template with no View involved. line() appends to the intro before action() is called, and to the
323
- * outro afterwards — exactly like Laravel's SimpleMessage.
376
+ * Laravel's Illuminate\Notifications\Messages\MailMessage: greeting/line/action/salutation, rendered to Laravel's
377
+ * default notification mail (HTML and text) with no View involved. line() appends to the intro before action() is
378
+ * called, and to the outro afterwards — exactly like Laravel's SimpleMessage.
324
379
  */
325
380
  declare class MailMessage {
381
+ /** info, success or error: the colour of the button, and error() greets with "Whoops!". Laravel's `$level`. */
382
+ levelName: MailLevel;
326
383
  subjectLine?: string;
327
384
  greetingLine?: string;
328
385
  introLines: string[];
@@ -333,19 +390,40 @@ declare class MailMessage {
333
390
  toAddresses: MailRecipient[];
334
391
  ccAddresses: MailRecipient[];
335
392
  bccAddresses: MailRecipient[];
393
+ replyToAddresses: MailRecipient[];
336
394
  fromAddress?: MailRecipient;
395
+ attachments: Attachment[];
396
+ /** A green button: something went well. */
397
+ success(): this;
398
+ /** A red button, and "Whoops!" when there is no greeting: something went wrong. */
399
+ error(): this;
400
+ level(level: MailLevel): this;
337
401
  subject(subject: string): this;
338
402
  greeting(greeting: string): this;
339
403
  /** Before action(), appends to the intro; after action(), to the outro. */
340
404
  line(text: string): this;
341
405
  lines(lines: string[]): this;
406
+ /** line(), when the condition holds. */
407
+ lineIf(condition: boolean, text: string): this;
408
+ /** lines(), when the condition holds. */
409
+ linesIf(condition: boolean, lines: string[]): this;
342
410
  action(text: string, url: string): this;
343
411
  salutation(salutation: string): this;
344
412
  from(address: MailRecipient): this;
345
413
  to(recipients: MailRecipient | MailRecipient[]): this;
346
414
  cc(recipients: MailRecipient | MailRecipient[]): this;
347
415
  bcc(recipients: MailRecipient | MailRecipient[]): this;
348
- /** Renders the default notification mail template. No ViewFactory involved. */
416
+ replyTo(recipients: MailRecipient | MailRecipient[]): this;
417
+ /** Attaches a file by its path: `as` names it in the mail (its file name by default), `mime` gives its type. */
418
+ attach(path: string, options?: {
419
+ as?: string;
420
+ mime?: string;
421
+ }): this;
422
+ /** Attaches bytes or text under a file name. */
423
+ attachData(data: Uint8Array | string, name: string, options?: {
424
+ mime?: string;
425
+ }): this;
426
+ /** Renders Laravel's default notification mail, HTML and text. No ViewFactory involved. */
349
427
  render(): {
350
428
  html: string;
351
429
  text: string;
@@ -425,7 +503,7 @@ declare class Dispatcher$2 implements NotificationDispatcher {
425
503
  * re-decides queued-or-now on whatever job it's handed — actually enqueues it instead of running it inline; the
426
504
  * notification's own queueability (checked by Dispatcher, above) only decides whether to wrap it at all. Like
427
505
  * Laravel's SendQueuedNotifications, it forwards failed(), retryUntil(), middleware() and displayName() to the
428
- * notification.
506
+ * notification. Unlike Laravel's, it is unique when the notification is (Laravel queues it past the unique lock).
429
507
  */
430
508
  declare class SendQueuedNotifications implements Job {
431
509
  readonly notifiables: Notifiable$1[];
@@ -987,7 +1065,7 @@ declare class RoutingServiceProvider extends ServiceProvider$1 {
987
1065
  declare class ThrottleRequests implements Middleware {
988
1066
  handle(request: HttpRequest, next: Next$1, maxAttempts?: string, decayMinutes?: string, prefix?: string): Promise<Response>;
989
1067
  /** The signed-in user's identifier, else the client IP, hashed (Laravel's resolveRequestSignature()). */
990
- protected resolveRequestSignature(request: HttpRequest): string;
1068
+ protected resolveRequestSignature(request: HttpRequest): Promise<string>;
991
1069
  }
992
1070
 
993
1071
  /**
@@ -1012,9 +1090,7 @@ declare function currentRequest(): HttpRequest | undefined;
1012
1090
  declare function optionalSession(): Session | undefined;
1013
1091
  declare function optionalCookieJar(): CookieJar$1 | undefined;
1014
1092
 
1015
- type ErrorsInput = Record<string, string | string[]> | {
1016
- toObject(): Record<string, string[]>;
1017
- };
1093
+ type ErrorsInput = Record<string, string | string[]> | MessageBag;
1018
1094
  /**
1019
1095
  * Laravel's RedirectResponse. with()/withErrors()/withInput() flash to the request's Session immediately, like
1020
1096
  * Laravel; without a bound Session (an API-only app) they are skipped silently.
@@ -1176,10 +1252,17 @@ declare class IncomingRequest implements HttpRequest {
1176
1252
  /** One route parameter (after model binding), or all of them. */
1177
1253
  route<T = unknown>(key?: string): T;
1178
1254
  session(): Session;
1179
- user<T = unknown>(guard?: string): T | undefined;
1255
+ /**
1256
+ * The signed-in user, through the resolver Auth sets, else the current scope's guard (the default, or `guard`).
1257
+ * The guard keeps the user it found, so it is looked up once per request. Undefined for a guest or without auth.
1258
+ */
1259
+ user<T = unknown>(guard?: string): Promise<T | undefined>;
1180
1260
  setUserResolver(resolver: (guard?: string) => unknown): void;
1181
- /** Validates all() through the ValidationFactory; throws its Validation error on failure. */
1182
- validate<T = Record<string, unknown>>(rules: Rules, messages?: Record<string, string>, attributes?: Record<string, string>): Promise<T>;
1261
+ /**
1262
+ * Validates all() through the ValidationFactory; throws its Validation error on failure. The data is typed from the
1263
+ * rules: `validate({ title: 'required|string' })` is `{ title: string }`.
1264
+ */
1265
+ validate<const R extends Rules>(rules: R, messages?: Record<string, string>, attributes?: Record<string, string>): Promise<InferValidatedType<R>>;
1183
1266
  }
1184
1267
 
1185
1268
  /** Helpers for request input: PHP-style bracket keys, safe cloning (no prototype pollution) and blank checks. */
@@ -1236,9 +1319,9 @@ declare function request<T = unknown>(key: string, defaultValue?: T): T;
1236
1319
  /** response() → the ResponseFactory; response(content, status, headers) → a Response. */
1237
1320
  declare function response(): ResponseFactory$1;
1238
1321
  declare function response(content: BodyInit | null, status?: number, headers?: HeadersInit): Response;
1239
- /** The Redirector with its route() typed by the generated route names. */
1322
+ /** The Redirector with its route() typed by the generated route names and their parameters. */
1240
1323
  type TypedRedirector = Omit<Redirector, 'route'> & {
1241
- route(name: RouteName, parameters?: unknown, status?: number): RedirectResponse;
1324
+ route<N extends RouteName>(name: N, ...args: RouteArguments<N, [status?: number]>): RedirectResponse;
1242
1325
  };
1243
1326
  /** redirect() → the Redirector; redirect('/path', status) → a RedirectResponse. */
1244
1327
  declare function redirect(): TypedRedirector;
@@ -1248,8 +1331,11 @@ declare function back(fallback?: string, status?: number): RedirectResponse;
1248
1331
  /** url() → the UrlGenerator; url('/path', query, absolute) → a URL. */
1249
1332
  declare function url(): UrlGenerator;
1250
1333
  declare function url(path: string, query?: Record<string, unknown>, absolute?: boolean): string;
1251
- /** The URL of a named route. */
1252
- declare function route(name: RouteName, parameters?: unknown, absolute?: boolean): string;
1334
+ /**
1335
+ * The URL of a named route: route('posts.show', post), route('posts.show', { post, page: 2 }). Once `oriel
1336
+ * route:types` has run, the name and the route's parameters are checked.
1337
+ */
1338
+ declare function route<N extends RouteName>(name: N, ...args: RouteArguments<N>): string;
1253
1339
  /** abort(404), abort(403, 'Nope', headers), or abort(response) to send a ready response. */
1254
1340
  declare function abort(status: number | Response, message?: string, headers?: Record<string, string>): never;
1255
1341
  declare function abortIf(condition: unknown, status: number | Response, message?: string, headers?: Record<string, string>): void;
@@ -1375,7 +1461,10 @@ declare class ExceptionsConfiguration implements ExceptionsConfigurator {
1375
1461
  /** Runs the withExceptions() callbacks against a handler (the provider does this when the handler is built). */
1376
1462
  declare function applyExceptionCallbacks(app: Application$2, handler: ErrorHandler): void;
1377
1463
 
1378
- /** Laravel's wording for the status (its error pages say "Server Error" and "Page Expired"). */
1464
+ /**
1465
+ * The text an error page shows for a status: Laravel's own wording where it has a view ("Server Error", "Page
1466
+ * Expired"), else Symfony's `Response::$statusTexts`, which Laravel shows for the others.
1467
+ */
1379
1468
  declare function statusText(status: number): string;
1380
1469
  declare function escapeHtml(value: string): string;
1381
1470
  /** Laravel's minimal error page: "404 | Not Found". */
@@ -1464,6 +1553,28 @@ declare function serve(app: Application$2, options?: ServeOptions): Promise<Runn
1464
1553
  */
1465
1554
  declare function servePublicFile(publicPath: string, request: Request): Promise<Response | undefined>;
1466
1555
 
1556
+ interface FileWatcher {
1557
+ close(): void;
1558
+ }
1559
+
1560
+ /** node:child_process's spawn(), replaceable in tests. */
1561
+ type SpawnServer = (command: string, args: string[], options: SpawnOptions) => ChildProcess;
1562
+ interface WatchedServerOptions {
1563
+ /** The server's command line: the runtime, its flags, the CLI script, then `serve --host=… --port=…`. */
1564
+ command: readonly string[];
1565
+ cwd: string;
1566
+ env: NodeJS.ProcessEnv;
1567
+ /** Starts watching: calls back with the changed files (relative to the base path) once they settle. */
1568
+ watch(onChange: (files: string[]) => void): FileWatcher;
1569
+ info(message: string): void;
1570
+ error(message: string): void;
1571
+ /** How long a server may take to stop before it is killed, in ms. Default 15000 (serve gives requests 10 s). */
1572
+ stopTimeout?: number;
1573
+ /** The signals that stop it. Default SIGINT, SIGTERM and SIGHUP. */
1574
+ signals?: readonly NodeJS.Signals[];
1575
+ spawn?: SpawnServer;
1576
+ }
1577
+
1467
1578
  interface RouteListRow {
1468
1579
  /** 'GET|HEAD' */
1469
1580
  readonly method: string;
@@ -1503,6 +1614,8 @@ interface HttpCommandOptions {
1503
1614
  serve?: (app: Application$2, options: ServeOptions) => Promise<RunningServer>;
1504
1615
  /** The terminal width for route:list. Default: process.stdout.columns, else 120. */
1505
1616
  terminalWidth?: () => number;
1617
+ /** Replaces `serve --watch`'s restarting server (tests). Resolves the command's exit code. */
1618
+ watch?: (options: WatchedServerOptions) => Promise<number>;
1506
1619
  }
1507
1620
  /** Registers `serve`, `route:list` and `install:api` as closure commands (PC1). */
1508
1621
  declare function registerHttpCommands(kernel: ConsoleKernel, app: Application$2, options?: HttpCommandOptions): void;
@@ -1531,16 +1644,18 @@ declare const Schedule: Facade<Schedule$1, object>;
1531
1644
 
1532
1645
  /**
1533
1646
  * Bootstraps the app for the `oriel` CLI: marks it as running in the console, boots every provider (Console's
1534
- * provider then loads routes/console.ts and app/Console/Commands), runs the command, and terminates the app, so
1535
- * terminating callbacks close the DB pools and other handles that would keep the process alive. `boot()` runs
1536
- * inside the try so a failure while booting still terminates the app. Relies on the process being started through
1537
- * a loader that understands .ts (tsx on Node, native on Bun), like the rest of the skeleton.
1647
+ * provider then loads routes/console.ts and app/Console/Commands), runs the command, and terminates the app, so its
1648
+ * terminating callbacks run after the command as they do after a request (closing the DB pools and other handles is
1649
+ * app.shutdown()'s job, which runConsoleAndExit() calls). `boot()` runs inside the try so a failure while booting
1650
+ * still terminates the app. Relies on the process being started through a loader that understands .ts (tsx on Node,
1651
+ * native on Bun), like the rest of the skeleton.
1538
1652
  */
1539
1653
  declare function runConsole(app: Application$2, argv?: string[]): Promise<number>;
1540
1654
  /**
1541
- * What the skeleton's `oriel` entry calls: runConsole(), then exit with the command's exit code. The log files are
1542
- * flushed first, also when the command throws: pino writes asynchronously and process.exit() doesn't wait, so a line
1543
- * logged just before would be lost, and pino's exit hook would throw (on Bun that made the exit code 1).
1655
+ * What the skeleton's `oriel` entry calls: runConsole(), then exit with the command's exit code. The app is shut down
1656
+ * first, also when the command throws: its shutdown callbacks close the database pools and Redis clients and write out
1657
+ * the log files (pino writes asynchronously and process.exit() doesn't wait, so a line logged just before would be
1658
+ * lost, and pino's exit hook would throw: on Bun that made the exit code 1).
1544
1659
  */
1545
1660
  declare function runConsoleAndExit(app: Application$2, argv?: string[], exit?: (code: number) => void): Promise<void>;
1546
1661
 
@@ -1579,6 +1694,15 @@ declare class ScheduledEventImpl implements ScheduledEvent {
1579
1694
  private readonly filters;
1580
1695
  private readonly rejects;
1581
1696
  private betweenWindow;
1697
+ private unlessWindow;
1698
+ private repeatEverySeconds;
1699
+ private readonly beforeCallbacks;
1700
+ /** Each is told whether the event succeeded (onSuccess() and onFailure() pick one side). */
1701
+ private readonly afterCallbacks;
1702
+ /** When run() last started (Laravel's lastChecked), for the every-N-seconds repetitions. */
1703
+ private lastChecked;
1704
+ /** The minute slot this server won with onOneServer(): its repetitions in that minute keep it. */
1705
+ private wonServerSlot;
1582
1706
  private overlapExpiryMinutes;
1583
1707
  private oneServer;
1584
1708
  private background;
@@ -1602,19 +1726,57 @@ declare class ScheduledEventImpl implements ScheduledEvent {
1602
1726
  everyFifteenMinutes(): this;
1603
1727
  everyThirtyMinutes(): this;
1604
1728
  hourly(): this;
1605
- hourlyAt(minute: number): this;
1729
+ hourlyAt(minute: number | readonly number[]): this;
1606
1730
  daily(): this;
1607
1731
  dailyAt(time: string): this;
1608
1732
  twiceDaily(first?: number, second?: number): this;
1609
1733
  weekly(): this;
1610
- weeklyOn(day: number, time?: string): this;
1734
+ weeklyOn(day: number | readonly number[], time?: string): this;
1611
1735
  monthly(): this;
1612
1736
  monthlyOn(day?: number, time?: string): this;
1613
1737
  yearly(): this;
1614
1738
  weekdays(): this;
1615
1739
  weekends(): this;
1740
+ everySecond(): this;
1741
+ everyTwoSeconds(): this;
1742
+ everyFiveSeconds(): this;
1743
+ everyTenSeconds(): this;
1744
+ everyFifteenSeconds(): this;
1745
+ everyTwentySeconds(): this;
1746
+ everyThirtySeconds(): this;
1747
+ everyTwoMinutes(): this;
1748
+ everyThreeMinutes(): this;
1749
+ everyFourMinutes(): this;
1750
+ everyTenMinutes(): this;
1751
+ everyOddHour(minute?: number | readonly number[]): this;
1752
+ everyTwoHours(minute?: number | readonly number[]): this;
1753
+ everyThreeHours(minute?: number | readonly number[]): this;
1754
+ everyFourHours(minute?: number | readonly number[]): this;
1755
+ everySixHours(minute?: number | readonly number[]): this;
1756
+ at(time: string): this;
1757
+ twiceDailyAt(first?: number, second?: number, minute?: number): this;
1758
+ mondays(): this;
1759
+ tuesdays(): this;
1760
+ wednesdays(): this;
1761
+ thursdays(): this;
1762
+ fridays(): this;
1763
+ saturdays(): this;
1764
+ sundays(): this;
1765
+ twiceMonthly(first?: number, second?: number, time?: string): this;
1766
+ /** Cron's `L`: the last day of whichever month it is, so a long-running schedule:work stays right. */
1767
+ lastDayOfMonth(time?: string): this;
1768
+ quarterly(): this;
1769
+ quarterlyOn(day?: number, time?: string): this;
1770
+ yearlyOn(month?: number, day?: number, time?: string): this;
1771
+ days(days: number | readonly number[], ...more: number[]): this;
1616
1772
  timezone(timezone: string): this;
1617
1773
  between(start: string, end: string): this;
1774
+ unlessBetween(start: string, end: string): this;
1775
+ before(callback: ScheduleHook): this;
1776
+ after(callback: ScheduleHook): this;
1777
+ then(callback: ScheduleHook): this;
1778
+ onSuccess(callback: ScheduleHook): this;
1779
+ onFailure(callback: ScheduleHook): this;
1618
1780
  when(callback: Filter): this;
1619
1781
  skip(callback: Filter): this;
1620
1782
  withoutOverlapping(expiresAtMinutes?: number): this;
@@ -1629,18 +1791,36 @@ declare class ScheduledEventImpl implements ScheduledEvent {
1629
1791
  /** The same as getSummaryForDisplay(). */
1630
1792
  getSummary(): string;
1631
1793
  isBackground(): boolean;
1794
+ /** The seconds between runs within a minute (everySecond() … everyThirtySeconds()), or undefined. */
1795
+ getRepeatSeconds(): number | undefined;
1796
+ /** Laravel's shouldRepeatNow(): an every-N-seconds event whose last run started N seconds ago or more. */
1797
+ shouldRepeatNow(now: number): boolean;
1798
+ /** Laravel's spliceIntoPosition(): replaces one cron field (0 = minute … 4 = day of the week). */
1799
+ private splice;
1800
+ private hourBased;
1801
+ private atTime;
1802
+ private repeatEvery;
1632
1803
  /**
1633
1804
  * Minute precision: `now` is truncated to the start of its minute, since cron-parser's includesDate() also
1634
1805
  * compares seconds. Without timezone(), expressions are read in app.timezone (UTC by default), as in Laravel.
1635
1806
  */
1636
1807
  isDue(now: Date): boolean;
1637
1808
  private zone;
1809
+ /** Whether `now`, in the event's time zone, falls in the window (inclusive; one that crosses midnight too). */
1638
1810
  private isWithinWindow;
1639
1811
  /**
1640
1812
  * `startedAt` is the moment the scheduler found this event due. onOneServer() keys its lock on that minute, so
1641
- * servers that start the event a little late still compete for the same slot.
1813
+ * servers that start the event a little late still compete for the same slot, and the server that wins keeps the
1814
+ * slot for the event's every-N-seconds repetitions in that minute. `checkedAt` is when this run starts (a
1815
+ * repetition's own moment), from which the next repetition counts.
1642
1816
  */
1643
- run(startedAt?: Date): Promise<void>;
1817
+ run(startedAt?: Date, checkedAt?: Date): Promise<void>;
1818
+ /**
1819
+ * Runs the event and says whether it failed. A command fails when it exits non-zero, and a closure when it throws or
1820
+ * returns false, as Laravel's CallbackEvent does. A job whose handler returns false failing is Oriel's own choice:
1821
+ * Laravel's Schedule::job() wraps the dispatch in a closure that returns nothing.
1822
+ */
1823
+ private execute;
1644
1824
  /**
1645
1825
  * Follows Laravel: a command event's mutex is `sha1(expression + full command
1646
1826
  * string incl. parameters)` (Laravel's `Event::mutexName()`) — no `name()` required. A closure event (`call()`/
@@ -1818,6 +1998,11 @@ declare abstract class GeneratorCommand extends Command {
1818
1998
  protected suffix(): string;
1819
1999
  /** Extra {{ placeholder }} values beyond {{ class }}. */
1820
2000
  protected extraPlaceholders(_rawName: string): Record<string, string>;
2001
+ /**
2002
+ * Runs once the target is known to be free (or --force is set) and before the file is rendered: where a generator
2003
+ * makes the files its own file imports (make:controller --model --requests), as Laravel does inside buildClass().
2004
+ */
2005
+ protected prepare(_rawName: string): Promise<void>;
1821
2006
  protected qualifyClass(rawName: string): {
1822
2007
  directories: string[];
1823
2008
  className: string;
@@ -1831,24 +2016,42 @@ declare abstract class GeneratorCommand extends Command {
1831
2016
  protected kind(): string;
1832
2017
  /** The import specifier from the generated file to `target` (an absolute path without extension): './X', '../Y/X'. */
1833
2018
  protected importPath(rawName: string, target: string): string;
2019
+ /** A --model value as studly segments: 'Admin/blog_post' -> ['Admin', 'BlogPost']; undefined when there is none. */
2020
+ protected modelSegments(value: unknown): string[] | undefined;
2021
+ /** The model's file under app/Models, without the extension (Laravel's qualifyModel() into App\Models). */
2022
+ protected modelPath(segments: string[]): string;
1834
2023
  handle(): Promise<number>;
1835
2024
  }
1836
2025
 
1837
2026
  declare class MakeControllerCommand extends GeneratorCommand {
1838
- readonly signature = "make:controller {name} {--resource} {--api} {--force}";
2027
+ readonly signature: string;
1839
2028
  description: string;
1840
2029
  protected type(): string;
1841
2030
  protected suffix(): string;
2031
+ /** Laravel's getStub(): --model, else --invokable, else --resource; --api picks the variant without create/edit. */
1842
2032
  protected stub(): string;
2033
+ handle(): Promise<number>;
2034
+ /**
2035
+ * With --model: the model is generated when app/Models has no file for it (Laravel asks, and --no-interaction
2036
+ * takes its default, yes), then with --requests the Store and Update form requests, as Laravel's buildClass().
2037
+ */
2038
+ protected prepare(): Promise<void>;
1843
2039
  protected extraPlaceholders(rawName: string): Record<string, string>;
1844
2040
  }
1845
2041
 
1846
2042
  declare class MakeModelCommand extends GeneratorCommand {
1847
- readonly signature = "make:model {name} {--m|migration} {--f|factory} {--s|seed} {--c|controller} {--resource} {--api} {--force}";
2043
+ readonly signature: string;
1848
2044
  description: string;
1849
2045
  protected type(): string;
1850
2046
  protected stub(): string;
2047
+ /** The factory make:factory writes for this model (database/factories/<Model>Factory.ts), for the model's type. */
2048
+ protected extraPlaceholders(rawName: string): Record<string, string>;
2049
+ /** Laravel's ModelMakeCommand::handle(): --all turns on every option but --api and --requests' own. */
1851
2050
  handle(): Promise<number>;
2051
+ /** The option, or --all, which sets factory, seed, migration, controller, policy and resource (and requests). */
2052
+ private wants;
2053
+ /** Laravel's class_basename() of the name, studly: Admin/blog_post → BlogPost. */
2054
+ private baseName;
1852
2055
  }
1853
2056
 
1854
2057
  declare class MakeCastCommand extends GeneratorCommand {
@@ -1901,12 +2104,22 @@ declare class MakeListenerCommand extends GeneratorCommand {
1901
2104
  protected extraPlaceholders(rawName: string): Record<string, string>;
1902
2105
  }
1903
2106
 
2107
+ /**
2108
+ * Laravel's make:mail with its view: the mailable renders `mail.<name>` (Laravel's getView() default), written to
2109
+ * resources/views as TSX. Laravel writes the view only with --view or --markdown; here it is always written, since a
2110
+ * mailable without its view fails on the first send. Oriel has no markdown mail, so there is no --markdown.
2111
+ */
1904
2112
  declare class MakeMailCommand extends GeneratorCommand {
1905
- readonly signature = "make:mail {name} {--force}";
2113
+ readonly signature: string;
1906
2114
  description: string;
1907
2115
  protected type(): string;
1908
2116
  protected stub(): string;
1909
2117
  protected extraPlaceholders(rawName: string): Record<string, string>;
2118
+ handle(): Promise<number>;
2119
+ /** --view, else `mail.` and the name's parts in kebab case: Orders/InvoicePaid → mail.orders.invoice-paid. */
2120
+ private viewName;
2121
+ /** Laravel's writeView(): an existing view is reported and left alone, even with --force. */
2122
+ private writeView;
1910
2123
  }
1911
2124
 
1912
2125
  declare class MakeMiddlewareCommand extends GeneratorCommand {
@@ -1932,11 +2145,16 @@ declare class MakeObserverCommand extends GeneratorCommand {
1932
2145
  }
1933
2146
 
1934
2147
  declare class MakePolicyCommand extends GeneratorCommand {
1935
- readonly signature = "make:policy {name} {--force}";
2148
+ readonly signature = "make:policy {name} {--m|model= : The model that the policy applies to} {--force : Create the class even if the policy already exists}";
1936
2149
  description: string;
1937
2150
  protected type(): string;
1938
2151
  protected suffix(): string;
1939
2152
  protected stub(): string;
2153
+ /**
2154
+ * Laravel's replaceModel(): the model from app/Models and the app's User model (app/Models/User, the skeleton's
2155
+ * auth model); the model's parameter is named `model` when the model is the User, so the two don't clash.
2156
+ */
2157
+ protected extraPlaceholders(rawName: string): Record<string, string>;
1940
2158
  }
1941
2159
 
1942
2160
  declare class MakeProviderCommand extends GeneratorCommand {
@@ -2018,6 +2236,29 @@ declare class ScheduleClearCacheCommand extends Command {
2018
2236
  handle(): Promise<number>;
2019
2237
  }
2020
2238
 
2239
+ /**
2240
+ * Laravel's schedule:interrupt: tells a running schedule:run (or schedule:work) to stop repeating its every-N-seconds
2241
+ * events for the rest of the minute, for a deploy. The signal lives in the cache until the minute ends.
2242
+ */
2243
+ declare class ScheduleInterruptCommand extends Command {
2244
+ private readonly clock;
2245
+ readonly signature = "schedule:interrupt";
2246
+ description: string;
2247
+ /** `now` is overridable so tests can say which minute it is. */
2248
+ constructor(clock?: {
2249
+ now?: () => number;
2250
+ });
2251
+ handle(): Promise<number>;
2252
+ }
2253
+
2254
+ /** The cache key schedule:interrupt sets until the minute ends (Laravel's `illuminate:schedule:interrupt`). */
2255
+ declare const SCHEDULE_INTERRUPT_KEY = "oriel:schedule:interrupt";
2256
+ /** The clock the repetitions read and wait on; the commands take their own so tests can move time on. */
2257
+ interface ScheduleClock {
2258
+ now: () => number;
2259
+ sleep: (ms: number) => Promise<void>;
2260
+ }
2261
+
2021
2262
  declare class ScheduleListCommand extends Command {
2022
2263
  readonly signature = "schedule:list";
2023
2264
  description: string;
@@ -2025,8 +2266,11 @@ declare class ScheduleListCommand extends Command {
2025
2266
  }
2026
2267
 
2027
2268
  declare class ScheduleRunCommand extends Command {
2269
+ private readonly clock;
2028
2270
  readonly signature = "schedule:run";
2029
2271
  description: string;
2272
+ /** `now` and `sleep` are overridable so tests don't wait out a real minute. */
2273
+ constructor(clock?: Partial<ScheduleClock>);
2030
2274
  handle(): Promise<number>;
2031
2275
  }
2032
2276
 
@@ -2257,6 +2501,8 @@ interface ColumnAttributes {
2257
2501
  after?: string;
2258
2502
  first?: boolean;
2259
2503
  onUpdate?: Expression;
2504
+ /** Set by change(): the column exists and is redefined, not added. */
2505
+ change?: boolean;
2260
2506
  }
2261
2507
  /** A column in a Blueprint, with Laravel's fluent modifiers: t.string('email').nullable().unique(). */
2262
2508
  declare class ColumnDefinition {
@@ -2282,6 +2528,12 @@ declare class ColumnDefinition {
2282
2528
  first(): this;
2283
2529
  /** default CURRENT_TIMESTAMP. */
2284
2530
  useCurrent(): this;
2531
+ /**
2532
+ * Redefines an existing column (Laravel's change()): t.string('title', 500).nullable().change(). As in Laravel 11+,
2533
+ * the column becomes exactly this definition: a modifier it had and that isn't given again (nullable, default,
2534
+ * comment, …) is dropped. On SQLite the table is rebuilt.
2535
+ */
2536
+ change(): this;
2285
2537
  /** MySQL only: on update CURRENT_TIMESTAMP. */
2286
2538
  useCurrentOnUpdate(): this;
2287
2539
  }
@@ -2342,8 +2594,12 @@ type BlueprintCommand = {
2342
2594
  from: string;
2343
2595
  to: string;
2344
2596
  } | {
2345
- name: 'dropPrimary' | 'dropUnique' | 'dropIndex' | 'dropForeign';
2597
+ name: 'dropPrimary' | 'dropUnique' | 'dropIndex';
2346
2598
  index: string;
2599
+ } | {
2600
+ name: 'dropForeign';
2601
+ index: string;
2602
+ columns?: string[];
2347
2603
  } | {
2348
2604
  name: 'rename';
2349
2605
  to: string;
@@ -2416,6 +2672,7 @@ declare class Blueprint {
2416
2672
  /** By name, or by columns (the conventional {table}_{columns}_unique name). */
2417
2673
  dropUnique(index: string | string[]): void;
2418
2674
  dropIndex(index: string | string[]): void;
2675
+ /** By name, or by columns (the conventional name; SQLite needs the columns, it doesn't keep foreign key names). */
2419
2676
  dropForeign(index: string | string[]): void;
2420
2677
  /** Drops the foreign key on the column, then the column. */
2421
2678
  dropConstrainedForeignId(column: string): void;
@@ -2426,6 +2683,10 @@ declare class Blueprint {
2426
2683
  rename(to: string): void;
2427
2684
  drop(): void;
2428
2685
  dropIfExists(): void;
2686
+ /** The columns this blueprint adds (not the ones change() redefines). */
2687
+ addedColumns(): ColumnDefinition[];
2688
+ /** The existing columns change() redefines (on a table being created, every column is added instead). */
2689
+ changedColumns(): ColumnDefinition[];
2429
2690
  /** Laravel's default index name: {table}_{columns}_{type}, lowercased, with - and . replaced by _. */
2430
2691
  createIndexName(type: IndexType | 'foreign', columns: string[]): string;
2431
2692
  /** The index commands implied by column modifiers (t.string('email').unique()), in column order. */
@@ -2446,6 +2707,42 @@ interface ColumnInfo {
2446
2707
  default: string | null;
2447
2708
  auto_increment: boolean;
2448
2709
  }
2710
+ /** One index of an existing table, as reported by Schema.getIndexes() (Laravel's shape). */
2711
+ interface IndexInfo {
2712
+ /** Lower-cased. The primary key is 'primary' on MySQL and on a SQLite rowid table, `{table}_pkey` on Postgres. */
2713
+ name: string;
2714
+ columns: string[];
2715
+ /** The index method ('btree', 'hash', …) on Postgres and MySQL; null on SQLite. */
2716
+ type: string | null;
2717
+ unique: boolean;
2718
+ primary: boolean;
2719
+ }
2720
+ /** One foreign key of an existing table, as reported by Schema.getForeignKeys() (Laravel's shape). */
2721
+ interface ForeignKeyInfo {
2722
+ /** The constraint name; null on SQLite, which doesn't keep it. */
2723
+ name: string | null;
2724
+ columns: string[];
2725
+ foreign_schema: string;
2726
+ foreign_table: string;
2727
+ /** Empty when a SQLite key names only the table (it then points at that table's primary key). */
2728
+ foreign_columns: string[];
2729
+ /** 'cascade', 'restrict', 'set null', 'set default' or 'no action'. */
2730
+ on_update: string;
2731
+ on_delete: string;
2732
+ }
2733
+ /**
2734
+ * A step a blueprint can't express as fixed SQL: on SQLite, rebuilding the table from its live definition plus these
2735
+ * key commands and changed columns. SchemaBuilder.build() runs it (Schema/SqliteTableRebuild.ts).
2736
+ */
2737
+ interface TableRebuild {
2738
+ readonly kind: 'rebuild';
2739
+ readonly table: string;
2740
+ readonly commands: BlueprintCommand[];
2741
+ readonly changes: ColumnDefinition[];
2742
+ }
2743
+ /** One step of a compiled blueprint: a statement, or a table rebuild. */
2744
+ type SchemaStep = Sql$1 | TableRebuild;
2745
+ declare const isTableRebuild: (step: SchemaStep) => step is TableRebuild;
2449
2746
  /**
2450
2747
  * Turns a Blueprint into DDL for one driver (Laravel's Schema\Grammars). Identifiers go through sql.id();
2451
2748
  * default values and comments are quoted literals (sql.lit); only DB.raw() defaults are written as-is.
@@ -2455,11 +2752,18 @@ declare abstract class SchemaGrammar {
2455
2752
  abstract readonly driver: DriverName;
2456
2753
  constructor(config?: Partial<ConnectionConfig$1>);
2457
2754
  static for(driver: DriverName, config?: Partial<ConnectionConfig$1>): SchemaGrammar;
2458
- /** Every statement for the blueprint: create/add first, then commands in order, then indexes from column modifiers. */
2755
+ /**
2756
+ * Every statement for the blueprint: create/add first, then commands in order, then indexes from column modifiers.
2757
+ * A blueprint that can only run against the live table (a SQLite rebuild) throws: run it with Schema.table().
2758
+ */
2459
2759
  compile(blueprint: Blueprint): Sql$1[];
2760
+ /** compile() with table rebuilds as steps of their own; consecutive rebuilds of one run are merged into one. */
2761
+ compileSteps(blueprint: Blueprint): SchemaStep[];
2460
2762
  protected compileCreate(blueprint: Blueprint, _commands: BlueprintCommand[], _handled: Set<BlueprintCommand>): Sql$1;
2461
2763
  protected compileAdd(blueprint: Blueprint, _commands: BlueprintCommand[], _handled: Set<BlueprintCommand>): Sql$1[];
2462
- protected compileCommand(blueprint: Blueprint, command: BlueprintCommand): Sql$1[];
2764
+ /** Redefines an existing column (change()). */
2765
+ protected abstract compileChange(blueprint: Blueprint, column: ColumnDefinition): SchemaStep[];
2766
+ protected compileCommand(blueprint: Blueprint, command: BlueprintCommand): SchemaStep[];
2463
2767
  compileRename(from: string, to: string): Sql$1;
2464
2768
  compileDrop(table: string): Sql$1;
2465
2769
  compileDropIfExists(table: string): Sql$1;
@@ -2486,16 +2790,28 @@ declare abstract class SchemaGrammar {
2486
2790
  abstract compileTables(): Sql$1;
2487
2791
  abstract compileColumns(table: string): Sql$1;
2488
2792
  abstract normalizeColumns(rows: Array<Record<string, unknown>>, tableSql?: string): ColumnInfo[];
2793
+ abstract compileIndexes(table: string): Sql$1;
2794
+ abstract normalizeIndexes(rows: Array<Record<string, unknown>>): IndexInfo[];
2795
+ abstract compileForeignKeys(table: string): Sql$1;
2796
+ abstract normalizeForeignKeys(rows: Array<Record<string, unknown>>): ForeignKeyInfo[];
2489
2797
  abstract compileEnableForeignKeyConstraints(): Sql$1;
2490
2798
  abstract compileDisableForeignKeyConstraints(): Sql$1;
2491
2799
  }
2492
2800
  declare class SqliteSchemaGrammar extends SchemaGrammar {
2493
2801
  readonly driver: "sqlite";
2494
- /** SQLite can't add keys to an existing table, so primary and foreign keys go inside create table. */
2802
+ /** A new table's primary and foreign keys go inside create table (adding them later rebuilds the table). */
2495
2803
  protected compileCreate(blueprint: Blueprint, commands: BlueprintCommand[], handled: Set<BlueprintCommand>): Sql$1;
2496
2804
  /** New columns may carry an inline `references` clause (the only foreign key SQLite can add later). */
2497
2805
  protected compileAdd(blueprint: Blueprint, commands: BlueprintCommand[], handled: Set<BlueprintCommand>): Sql$1[];
2498
- protected compileCommand(blueprint: Blueprint, command: BlueprintCommand): Sql$1[];
2806
+ /**
2807
+ * SQLite can't add or drop a primary or foreign key on an existing table: those commands rebuild the table (Laravel
2808
+ * 11+'s compileAlter), as a step SchemaBuilder.build() runs against the live table.
2809
+ */
2810
+ protected compileCommand(blueprint: Blueprint, command: BlueprintCommand): SchemaStep[];
2811
+ /** SQLite can't alter a column: changing one rebuilds the table with the new definition. */
2812
+ protected compileChange(blueprint: Blueprint, column: ColumnDefinition): SchemaStep[];
2813
+ /** `foreign key (…) references … on delete …`, a table constraint of a rebuilt table. */
2814
+ compileForeignKeyConstraint(foreign: ForeignKeyDefinition): Sql$1;
2499
2815
  protected compileUnique(blueprint: Blueprint, index: string, columns: string[]): Sql$1;
2500
2816
  protected compileDropUnique(_blueprint: Blueprint, index: string): Sql$1;
2501
2817
  protected type(column: ColumnDefinition): Sql$1;
@@ -2503,17 +2819,34 @@ declare class SqliteSchemaGrammar extends SchemaGrammar {
2503
2819
  compileTables(): Sql$1;
2504
2820
  compileColumns(table: string): Sql$1;
2505
2821
  normalizeColumns(rows: Array<Record<string, unknown>>): ColumnInfo[];
2822
+ /** Laravel's query: the primary key from pragma_table_xinfo, then every index of pragma_index_list with its columns. */
2823
+ compileIndexes(table: string): Sql$1;
2824
+ /** A table whose primary key has its own index (not a rowid alias) lists it twice: the index entry is kept. */
2825
+ normalizeIndexes(rows: Array<Record<string, unknown>>): IndexInfo[];
2826
+ compileForeignKeys(table: string): Sql$1;
2827
+ normalizeForeignKeys(rows: Array<Record<string, unknown>>): ForeignKeyInfo[];
2506
2828
  compileEnableForeignKeyConstraints(): Sql$1;
2507
2829
  compileDisableForeignKeyConstraints(): Sql$1;
2508
2830
  }
2509
2831
  declare class PostgresSchemaGrammar extends SchemaGrammar {
2510
2832
  readonly driver: "pgsql";
2833
+ /** A changed column's comment is set again, or cleared (`is NULL`) when the new definition has none (Laravel 11+). */
2511
2834
  protected compileComments(blueprint: Blueprint): Sql$1[];
2835
+ /**
2836
+ * Laravel's compileChange(): `alter column` for the type, the nullability and the default, in one statement. A serial
2837
+ * type becomes its integer type (the sequence stays), and an auto-increment column keeps its default. No `using`
2838
+ * clause: a change Postgres can't cast implicitly fails, as in Laravel.
2839
+ */
2840
+ protected compileChange(blueprint: Blueprint, column: ColumnDefinition): SchemaStep[];
2512
2841
  protected type(column: ColumnDefinition): Sql$1;
2513
2842
  protected modifiers(column: ColumnDefinition): Sql$1[];
2514
2843
  compileTables(): Sql$1;
2515
2844
  compileColumns(table: string): Sql$1;
2516
2845
  normalizeColumns(rows: Array<Record<string, unknown>>): ColumnInfo[];
2846
+ compileIndexes(table: string): Sql$1;
2847
+ normalizeIndexes(rows: Array<Record<string, unknown>>): IndexInfo[];
2848
+ compileForeignKeys(table: string): Sql$1;
2849
+ normalizeForeignKeys(rows: Array<Record<string, unknown>>): ForeignKeyInfo[];
2517
2850
  compileEnableForeignKeyConstraints(): Sql$1;
2518
2851
  compileDisableForeignKeyConstraints(): Sql$1;
2519
2852
  }
@@ -2521,6 +2854,8 @@ declare class MySqlSchemaGrammar extends SchemaGrammar {
2521
2854
  readonly driver: "mysql";
2522
2855
  protected compileCreate(blueprint: Blueprint, commands: BlueprintCommand[], handled: Set<BlueprintCommand>): Sql$1;
2523
2856
  protected compileAdd(blueprint: Blueprint): Sql$1[];
2857
+ /** Laravel's compileChange(): `modify` with the column's whole new definition. */
2858
+ protected compileChange(blueprint: Blueprint, column: ColumnDefinition): SchemaStep[];
2524
2859
  protected compileUnique(blueprint: Blueprint, index: string, columns: string[]): Sql$1;
2525
2860
  protected compileIndex(blueprint: Blueprint, index: string, columns: string[]): Sql$1;
2526
2861
  protected compileDropPrimary(blueprint: Blueprint): Sql$1;
@@ -2532,6 +2867,10 @@ declare class MySqlSchemaGrammar extends SchemaGrammar {
2532
2867
  compileTables(): Sql$1;
2533
2868
  compileColumns(table: string): Sql$1;
2534
2869
  normalizeColumns(rows: Array<Record<string, unknown>>): ColumnInfo[];
2870
+ compileIndexes(table: string): Sql$1;
2871
+ normalizeIndexes(rows: Array<Record<string, unknown>>): IndexInfo[];
2872
+ compileForeignKeys(table: string): Sql$1;
2873
+ normalizeForeignKeys(rows: Array<Record<string, unknown>>): ForeignKeyInfo[];
2535
2874
  compileEnableForeignKeyConstraints(): Sql$1;
2536
2875
  compileDisableForeignKeyConstraints(): Sql$1;
2537
2876
  }
@@ -2554,7 +2893,10 @@ declare class SchemaBuilder {
2554
2893
  drop(table: string): Promise<void>;
2555
2894
  dropIfExists(table: string): Promise<void>;
2556
2895
  rename(from: string, to: string): Promise<void>;
2557
- /** Runs a blueprint's statements. Also useful to inspect the DDL: grammar.compile(blueprint). */
2896
+ /**
2897
+ * Runs a blueprint's statements in order (inspect them with grammar.compile(blueprint)). On SQLite, a change to the
2898
+ * keys of an existing table rebuilds it from its live definition at its place in that order.
2899
+ */
2558
2900
  build(blueprint: Blueprint): Promise<void>;
2559
2901
  /** The table names of the connection's database (or current schema on Postgres). */
2560
2902
  getTables(): Promise<string[]>;
@@ -2564,6 +2906,16 @@ declare class SchemaBuilder {
2564
2906
  /** Case-insensitive, like Laravel. */
2565
2907
  hasColumn(table: string, column: string): Promise<boolean>;
2566
2908
  hasColumns(table: string, columns: string[]): Promise<boolean>;
2909
+ /** The table's indexes, its primary key included (Laravel's getIndexes()). */
2910
+ getIndexes(table: string): Promise<IndexInfo[]>;
2911
+ getIndexListing(table: string): Promise<string[]>;
2912
+ /**
2913
+ * Whether the table has an index with this name, or on exactly these columns (in order). `type` narrows it:
2914
+ * 'primary', 'unique', or an index method such as 'btree'.
2915
+ */
2916
+ hasIndex(table: string, index: string | string[], type?: string): Promise<boolean>;
2917
+ /** The table's foreign keys (Laravel's getForeignKeys()). */
2918
+ getForeignKeys(table: string): Promise<ForeignKeyInfo[]>;
2567
2919
  enableForeignKeyConstraints(): Promise<void>;
2568
2920
  disableForeignKeyConstraints(): Promise<void>;
2569
2921
  /**
@@ -2833,6 +3185,13 @@ declare class Grammar {
2833
3185
  compileOrders(query: Builder$1<unknown>): Sql | undefined;
2834
3186
  compileWheres(wheres: readonly Where[], keyword?: 'where' | 'on'): Sql | undefined;
2835
3187
  compileWhere(where: Where): Sql;
3188
+ /**
3189
+ * whereDate(), whereTime(), whereDay(), whereMonth() and whereYear() per driver, as Laravel 12's grammars: MySQL's
3190
+ * date()/time()/day()/month()/year(), Postgres' ::date, ::time and extract(), SQLite's strftime() compared as text.
3191
+ */
3192
+ compileWhereDate(where: Extract<Where, {
3193
+ type: 'date';
3194
+ }>): Sql;
2836
3195
  /**
2837
3196
  * whereLike() per driver, as Laravel 12's grammars: Postgres compares the column as text with ilike (like when
2838
3197
  * case-sensitive); MySQL uses like (like binary); SQLite uses like, or glob with the pattern translated.
@@ -2915,7 +3274,20 @@ type Where = {
2915
3274
  sql: string;
2916
3275
  bindings: readonly unknown[];
2917
3276
  boolean: WhereBoolean;
3277
+ } | {
3278
+ type: 'date';
3279
+ part: DatePart;
3280
+ column: ColumnRef;
3281
+ operator: string;
3282
+ value: unknown;
3283
+ boolean: WhereBoolean;
2918
3284
  };
3285
+ /** The part of a date or time column a date where clause compares (whereDate() → 'date', whereYear() → 'year', …). */
3286
+ type DatePart = 'date' | 'time' | 'day' | 'month' | 'year';
3287
+ /** What a date where clause compares with: a Date (read in UTC), a string, a number, or DB.raw(). */
3288
+ type DateWhereValue = Date | string | number | Expression;
3289
+ /** whereDate('published_at', '2026-01-05') or whereDate('published_at', '>=', new Date()). */
3290
+ type DateWhereArgs = [value: DateWhereValue] | [operator: string, value: DateWhereValue];
2919
3291
  type Having = {
2920
3292
  column: ColumnRef;
2921
3293
  operator: string;
@@ -2931,9 +3303,11 @@ type Order = {
2931
3303
  } | {
2932
3304
  raw: Expression;
2933
3305
  };
3306
+ /** A column, an expression, or `(subquery) as alias` (`exists (subquery) as alias` with exists). */
2934
3307
  type SelectColumn = ColumnRef | {
2935
3308
  query: Builder$1<unknown>;
2936
3309
  as: string;
3310
+ exists?: boolean;
2937
3311
  };
2938
3312
  type NestedCallback<Q> = (query: Q) => unknown;
2939
3313
  /** The value when()'s callback receives: the condition's type without its falsy members. */
@@ -2988,6 +3362,21 @@ declare class Builder$1<T = Row> implements QueryBuilder<T> {
2988
3362
  whereBetween(column: ColumnRef, values: readonly [unknown, unknown]): this;
2989
3363
  orWhereBetween(column: ColumnRef, values: readonly [unknown, unknown]): this;
2990
3364
  whereNotBetween(column: ColumnRef, values: readonly [unknown, unknown]): this;
3365
+ /** Compares the date part of a column: whereDate('published_at', '2026-01-05'), whereDate('published_at', '<', new Date()). */
3366
+ whereDate(column: ColumnRef, ...args: DateWhereArgs): this;
3367
+ orWhereDate(column: ColumnRef, ...args: DateWhereArgs): this;
3368
+ /** Compares the time of day: whereTime('published_at', '>=', '09:00:00'). */
3369
+ whereTime(column: ColumnRef, ...args: DateWhereArgs): this;
3370
+ orWhereTime(column: ColumnRef, ...args: DateWhereArgs): this;
3371
+ /** Compares the day of the month: whereDay('published_at', 5). */
3372
+ whereDay(column: ColumnRef, ...args: DateWhereArgs): this;
3373
+ orWhereDay(column: ColumnRef, ...args: DateWhereArgs): this;
3374
+ /** Compares the month: whereMonth('published_at', 12). */
3375
+ whereMonth(column: ColumnRef, ...args: DateWhereArgs): this;
3376
+ orWhereMonth(column: ColumnRef, ...args: DateWhereArgs): this;
3377
+ /** Compares the year: whereYear('published_at', '>=', 2026). */
3378
+ whereYear(column: ColumnRef, ...args: DateWhereArgs): this;
3379
+ orWhereYear(column: ColumnRef, ...args: DateWhereArgs): this;
2991
3380
  /**
2992
3381
  * Laravel's whereLike(): the value is the pattern, `%` and `_` included (`whereLike('title', `%${term}%`)`).
2993
3382
  * Case-insensitive unless caseSensitive: ilike on Postgres, like on MySQL and SQLite (their like already ignores
@@ -3048,6 +3437,8 @@ declare class Builder$1<T = Row> implements QueryBuilder<T> {
3048
3437
  unless<V>(value: V, callback: (query: this, value: V) => unknown, otherwise?: (query: this, value: Truthy<V>) => unknown): this;
3049
3438
  tap(callback: (query: this) => unknown): this;
3050
3439
  get(): Promise<Collection<T>>;
3440
+ /** The collection get() and chunk() hand out (Eloquent's builder makes the model's collection). */
3441
+ protected newCollection(items: T[]): Collection<T>;
3051
3442
  /** The raw rows, without a Collection around them. */
3052
3443
  runSelect(): Promise<T[]>;
3053
3444
  first(): Promise<T | undefined>;
@@ -3128,6 +3519,8 @@ declare class Builder$1<T = Row> implements QueryBuilder<T> {
3128
3519
  private subQuery;
3129
3520
  private addNested;
3130
3521
  private addWhere;
3522
+ /** Laravel's addDateBasedWhere(): one value means '='; the operator is checked against the whitelist. */
3523
+ private addDateBasedWhere;
3131
3524
  private pushNull;
3132
3525
  }
3133
3526
  type JoinType = 'inner' | 'left' | 'right' | 'cross';
@@ -3235,6 +3628,106 @@ declare const SchemaBuilderToken: Token<SchemaBuilder>;
3235
3628
  /** The Schema facade: Schema.create('posts', (t) => { … }), Schema.table(…), Schema.dropIfExists(…). */
3236
3629
  declare const Schema: Facade<SchemaBuilder, object>;
3237
3630
 
3631
+ /**
3632
+ * A custom cast (Laravel's CastsAttributes): get() turns the stored value into what the model exposes, set() turns
3633
+ * an assigned value back into what is stored.
3634
+ */
3635
+ interface CastsAttributes<TGet = unknown, TSet = TGet> {
3636
+ get(model: object, key: string, value: unknown, attributes: Row): TGet;
3637
+ set(model: object, key: string, value: TSet, attributes: Row): unknown;
3638
+ }
3639
+ /** A TypeScript enum object (string or numeric) used as a cast: casts = { status: PostStatus }. */
3640
+ type EnumLike$1 = Record<string, string | number>;
3641
+ type BuiltInCast = 'int' | 'integer' | 'float' | 'double' | 'real' | 'string' | 'bool' | 'boolean' | 'array' | 'json' | 'object' | 'collection' | 'date' | 'datetime' | 'immutable_date' | 'immutable_datetime' | 'timestamp' | 'hashed' | `decimal:${number}`;
3642
+ type CastDefinition = BuiltInCast | EnumLike$1 | CastsAttributes | (new () => CastsAttributes);
3643
+ /** The values of a TypeScript enum. Numeric enums also map values back to names; those reverse entries are skipped. */
3644
+ declare function enumValues(cast: EnumLike$1): Array<string | number>;
3645
+ declare const isJsonCast: (cast: CastDefinition | undefined) => boolean;
3646
+ declare const isDateCast: (cast: CastDefinition | undefined) => boolean;
3647
+ /** Laravel's castAttribute(): the stored value → the value the model exposes. null stays null (except custom casts). */
3648
+ declare function castGet(model: object, key: string, cast: CastDefinition, value: unknown, attributes: Row, className: string): unknown;
3649
+ /** The value assigned to a cast attribute → the value stored in the model's attributes (and later bound). */
3650
+ declare function castSet(model: object, key: string, cast: CastDefinition, value: unknown, attributes: Row, className: string): unknown;
3651
+ /**
3652
+ * Laravel's originalIsEquivalent(): does the stored value still mean the same thing as the original?
3653
+ * Keeps save() from writing columns whose value only changed representation (1 vs true, '5' vs 5, same instant).
3654
+ */
3655
+ declare function isEquivalent(cast: CastDefinition | undefined, current: unknown, original: unknown, model: object, key: string, className: string): boolean;
3656
+
3657
+ /**
3658
+ * Laravel's Eloquent collection: what every query, relation and eager load of models returns. It is a support
3659
+ * Collection (methods that keep the items keep this class; map() and the other type-changing methods return a plain
3660
+ * Collection) with the model-aware methods: find() by key, load() and loadCount() for every model at once, fresh(),
3661
+ * modelKeys(), toQuery(), and diff()/intersect()/unique()/only()/except()/merge() that compare models by key.
3662
+ */
3663
+ declare class EloquentCollection<M extends Model = Model> extends Collection<M> {
3664
+ /** The model with this key (or this model's key), else the default; with several keys, those models. */
3665
+ find(key: readonly unknown[] | Collection<unknown>): this;
3666
+ find(key: unknown): M | undefined;
3667
+ find<D>(key: unknown, defaultValue: D): M | D;
3668
+ /** find(), or ModelNotFoundError naming the missing keys. */
3669
+ findOrFail(keys: readonly unknown[] | Collection<unknown>): this;
3670
+ findOrFail(key: unknown): M;
3671
+ /** The primary keys, in order. */
3672
+ modelKeys(): unknown[];
3673
+ /** The models keyed by their primary key (as text). */
3674
+ getDictionary(items?: Iterable<M>): Record<string, M>;
3675
+ /** The same models in a plain Collection. */
3676
+ toBase(): Collection<M>;
3677
+ /** Whether a model with this key (or this model) is in the collection; the other forms are Collection's. */
3678
+ contains(key: keyof M & string, value: unknown): boolean;
3679
+ contains(key: (keyof M & string) | ((item: M) => unknown), operator: Operator$1, value: unknown): boolean;
3680
+ contains(callback: (item: M) => boolean): boolean;
3681
+ contains(value: unknown): boolean;
3682
+ /** Collection's containsStrict(): a model matches only itself (no key matching). */
3683
+ containsStrict(key: keyof M & string, value: unknown): boolean;
3684
+ containsStrict(callback: (item: M) => boolean): boolean;
3685
+ containsStrict(value: unknown): boolean;
3686
+ /** Collection's doesntContainStrict(): a model matches only itself (no key matching). */
3687
+ doesntContainStrict(key: keyof M & string, value: unknown): boolean;
3688
+ doesntContainStrict(callback: (item: M) => boolean): boolean;
3689
+ doesntContainStrict(value: unknown): boolean;
3690
+ /** Eager loads relations onto every model, one query per relation: await posts.load('author', 'comments.author'). */
3691
+ load(...relations: EagerLoadSpec[]): Promise<this>;
3692
+ /** Loads only the relations that aren't loaded yet; nested paths are followed into the loaded relations. */
3693
+ loadMissing(...relations: string[]): Promise<this>;
3694
+ /** Adds <relation>_count attributes to every model with one query: await posts.loadCount('comments'). */
3695
+ loadCount(...relations: EagerLoadSpec[]): Promise<this>;
3696
+ /**
3697
+ * Laravel's loadAggregate(): withAggregate() for models already loaded, with one query for the whole collection.
3698
+ * The values become clean attributes (with their casts: loadExists() gives booleans).
3699
+ */
3700
+ loadAggregate(relations: EagerLoadSpec | EagerLoadSpec[], column: string | Expression, fn?: string): Promise<this>;
3701
+ /** Adds <relation>_sum_<column> to every model: await users.loadSum('orders', 'price'). */
3702
+ loadSum(relations: EagerLoadSpec | EagerLoadSpec[], column: string | Expression): Promise<this>;
3703
+ loadAvg(relations: EagerLoadSpec | EagerLoadSpec[], column: string | Expression): Promise<this>;
3704
+ loadMin(relations: EagerLoadSpec | EagerLoadSpec[], column: string | Expression): Promise<this>;
3705
+ loadMax(relations: EagerLoadSpec | EagerLoadSpec[], column: string | Expression): Promise<this>;
3706
+ /** Adds a boolean <relation>_exists to every model. */
3707
+ loadExists(...relations: EagerLoadSpec[]): Promise<this>;
3708
+ /** The models as they are in the database now (without global scopes), with relations loaded; deleted ones drop out. */
3709
+ fresh(...relations: EagerLoadSpec[]): Promise<this>;
3710
+ /** The models whose keys aren't in the given models. */
3711
+ diff(items: Iterable<M>): this;
3712
+ /** The models whose keys are also in the given models. */
3713
+ intersect(items: Iterable<M>): this;
3714
+ /** One model per key (the last instance, at the first one's place); with a key or callback, Collection's unique(). */
3715
+ unique(key?: (keyof M & string) | ((item: M) => unknown)): this;
3716
+ /** The models with these keys, in the collection's order. */
3717
+ only(...keys: unknown[]): this;
3718
+ /** The models without these keys, in the collection's order. */
3719
+ except(...keys: unknown[]): this;
3720
+ /** Adds the given models, replacing the ones with the same key. */
3721
+ merge(items: Iterable<M>): this;
3722
+ makeHidden(...attributes: Array<string | string[]>): this;
3723
+ makeVisible(...attributes: Array<string | string[]>): this;
3724
+ setVisible(visible: string[]): this;
3725
+ setHidden(hidden: string[]): this;
3726
+ append(...attributes: Array<string | string[]>): this;
3727
+ /** A query of exactly these models (where key in …), for mass updates: await posts.toQuery().update({ … }). */
3728
+ toQuery(): Builder<M>;
3729
+ }
3730
+
3238
3731
  /**
3239
3732
  * A relation is the related model's query builder, constrained to the parent: post.comments() is a
3240
3733
  * Builder<Comment> with `where comments.post_id = ?`, so every builder method (where, orderBy, paginate, a local
@@ -3336,6 +3829,8 @@ declare class Builder<M extends Model = Model> extends Builder$1<M> {
3336
3829
  protected scopes: Map<string, GlobalScope>;
3337
3830
  protected removedScopes: string[];
3338
3831
  protected eagerLoad: Map<string, RelationConstraint | undefined>;
3832
+ /** Casts for the selected columns (withCasts()), merged into every model this query hydrates. */
3833
+ protected selectCasts: Record<string, CastDefinition>;
3339
3834
  constructor(model: M);
3340
3835
  getModel(): M;
3341
3836
  /** The model class's static scope<Name> method for a builder method name, if any. */
@@ -3366,6 +3861,16 @@ declare class Builder<M extends Model = Model> extends Builder$1<M> {
3366
3861
  whereNull(columns: Column<M> | Expression | Array<Column<M> | Expression>): this;
3367
3862
  whereNotNull(columns: Column<M> | Expression | Array<Column<M> | Expression>): this;
3368
3863
  whereBetween(column: Column<M> | Expression, values: readonly [unknown, unknown]): this;
3864
+ whereDate(column: Column<M> | Expression, ...args: DateWhereArgs): this;
3865
+ orWhereDate(column: Column<M> | Expression, ...args: DateWhereArgs): this;
3866
+ whereTime(column: Column<M> | Expression, ...args: DateWhereArgs): this;
3867
+ orWhereTime(column: Column<M> | Expression, ...args: DateWhereArgs): this;
3868
+ whereDay(column: Column<M> | Expression, ...args: DateWhereArgs): this;
3869
+ orWhereDay(column: Column<M> | Expression, ...args: DateWhereArgs): this;
3870
+ whereMonth(column: Column<M> | Expression, ...args: DateWhereArgs): this;
3871
+ orWhereMonth(column: Column<M> | Expression, ...args: DateWhereArgs): this;
3872
+ whereYear(column: Column<M> | Expression, ...args: DateWhereArgs): this;
3873
+ orWhereYear(column: Column<M> | Expression, ...args: DateWhereArgs): this;
3369
3874
  whereLike(column: Column<M> | Expression, value: string, caseSensitive?: boolean, boolean?: WhereBoolean, not?: boolean): this;
3370
3875
  orWhereLike(column: Column<M> | Expression, value: string, caseSensitive?: boolean): this;
3371
3876
  whereNotLike(column: Column<M> | Expression, value: string, caseSensitive?: boolean, boolean?: WhereBoolean): this;
@@ -3378,6 +3883,12 @@ declare class Builder<M extends Model = Model> extends Builder$1<M> {
3378
3883
  /** where key = id (or key in ids). */
3379
3884
  whereKey(id: unknown): this;
3380
3885
  whereKeyNot(id: unknown): this;
3886
+ /** The models, in the model's collection (an EloquentCollection). */
3887
+ get(): Promise<EloquentCollection<M>>;
3888
+ protected newCollection(models: M[]): EloquentCollection<M>;
3889
+ /** chunk() with each chunk in the model's collection. */
3890
+ chunk(count: number, callback: (models: EloquentCollection<M>, page: number) => unknown): Promise<boolean>;
3891
+ chunkById(count: number, callback: (models: EloquentCollection<M>, page: number) => unknown, column?: string, alias?: string): Promise<boolean>;
3381
3892
  /** Runs the query, hydrates models, fires their retrieved events and eager loads the with() relations. */
3382
3893
  runSelect(): Promise<M[]>;
3383
3894
  /**
@@ -3400,6 +3911,25 @@ declare class Builder<M extends Model = Model> extends Builder$1<M> {
3400
3911
  * withCount('comments as approved_count'). Global scopes of the related model (soft deletes) apply.
3401
3912
  */
3402
3913
  withCount(...relations: EagerLoadSpec[]): this;
3914
+ /** Adds `<relation>_sum_<column>`: withSum('orders', 'price'), withSum({ 'orders as paid': (q) => … }, 'price'). */
3915
+ withSum(relations: EagerLoadSpec | EagerLoadSpec[], column: string | Expression): this;
3916
+ /** Adds `<relation>_avg_<column>`. */
3917
+ withAvg(relations: EagerLoadSpec | EagerLoadSpec[], column: string | Expression): this;
3918
+ /** Adds `<relation>_min_<column>`. */
3919
+ withMin(relations: EagerLoadSpec | EagerLoadSpec[], column: string | Expression): this;
3920
+ /** Adds `<relation>_max_<column>`. */
3921
+ withMax(relations: EagerLoadSpec | EagerLoadSpec[], column: string | Expression): this;
3922
+ /** Adds a boolean `<relation>_exists`: withExists('comments'). */
3923
+ withExists(...relations: EagerLoadSpec[]): this;
3924
+ /**
3925
+ * Laravel's withAggregate(): a correlated subquery per relation, `select <fn>(<related column>) … as <alias>`, the
3926
+ * alias being `<relation>_<fn>_<column>` unless the relation is named `'orders as alias'`. The relation's
3927
+ * constraint and the related model's global scopes apply; orderings are dropped. 'exists' selects
3928
+ * `exists (…)`, cast to a boolean. Without a function the column's first value is selected.
3929
+ */
3930
+ withAggregate(relations: EagerLoadSpec | EagerLoadSpec[], column: string | Expression, fn?: string): this;
3931
+ /** Casts for selected columns, as if the model declared them: withCasts({ orders_sum_price: 'float' }). */
3932
+ withCasts(casts: Readonly<Record<string, CastDefinition>>): this;
3403
3933
  /**
3404
3934
  * Rows that have related rows: has('comments'), has('comments', '>=', 3), has('comments.author').
3405
3935
  * Uses `exists (…)` for the common "at least one"/"none" cases and a count subquery otherwise.
@@ -3426,9 +3956,9 @@ declare class Builder<M extends Model = Model> extends Builder$1<M> {
3426
3956
  protected isMalformedKey(id: unknown): boolean;
3427
3957
  /** A malformed unique id (HasUuids, HasUlids) finds nothing without a query, as route model binding does. */
3428
3958
  find(id: unknown): Promise<M | undefined>;
3429
- findMany(ids: readonly unknown[]): Promise<Collection<M>>;
3959
+ findMany(ids: readonly unknown[]): Promise<EloquentCollection<M>>;
3430
3960
  /** find(), or ModelNotFoundError (a 404). With an array, every id must exist. */
3431
- findOrFail(ids: readonly unknown[]): Promise<Collection<M>>;
3961
+ findOrFail(ids: readonly unknown[]): Promise<EloquentCollection<M>>;
3432
3962
  findOrFail(id: unknown): Promise<M>;
3433
3963
  findOr<R>(id: unknown, callback: () => R | Promise<R>): Promise<M | R>;
3434
3964
  firstOrFail(): Promise<M>;
@@ -3474,32 +4004,6 @@ declare class Builder<M extends Model = Model> extends Builder$1<M> {
3474
4004
  protected defaultPerPage(): number;
3475
4005
  }
3476
4006
 
3477
- /**
3478
- * A custom cast (Laravel's CastsAttributes): get() turns the stored value into what the model exposes, set() turns
3479
- * an assigned value back into what is stored.
3480
- */
3481
- interface CastsAttributes<TGet = unknown, TSet = TGet> {
3482
- get(model: object, key: string, value: unknown, attributes: Row): TGet;
3483
- set(model: object, key: string, value: TSet, attributes: Row): unknown;
3484
- }
3485
- /** A TypeScript enum object (string or numeric) used as a cast: casts = { status: PostStatus }. */
3486
- type EnumLike = Record<string, string | number>;
3487
- type BuiltInCast = 'int' | 'integer' | 'float' | 'double' | 'real' | 'string' | 'bool' | 'boolean' | 'array' | 'json' | 'object' | 'collection' | 'date' | 'datetime' | 'immutable_date' | 'immutable_datetime' | 'timestamp' | `decimal:${number}`;
3488
- type CastDefinition = BuiltInCast | EnumLike | CastsAttributes | (new () => CastsAttributes);
3489
- /** The values of a TypeScript enum. Numeric enums also map values back to names; those reverse entries are skipped. */
3490
- declare function enumValues(cast: EnumLike): Array<string | number>;
3491
- declare const isJsonCast: (cast: CastDefinition | undefined) => boolean;
3492
- declare const isDateCast: (cast: CastDefinition | undefined) => boolean;
3493
- /** Laravel's castAttribute(): the stored value → the value the model exposes. null stays null (except custom casts). */
3494
- declare function castGet(model: object, key: string, cast: CastDefinition, value: unknown, attributes: Row, className: string): unknown;
3495
- /** The value assigned to a cast attribute → the value stored in the model's attributes (and later bound). */
3496
- declare function castSet(model: object, key: string, cast: CastDefinition, value: unknown, attributes: Row, className: string): unknown;
3497
- /**
3498
- * Laravel's originalIsEquivalent(): does the stored value still mean the same thing as the original?
3499
- * Keeps save() from writing columns whose value only changed representation (1 vs true, '5' vs 5, same instant).
3500
- */
3501
- declare function isEquivalent(cast: CastDefinition | undefined, current: unknown, original: unknown, model: object, key: string, className: string): boolean;
3502
-
3503
4007
  declare const MANY: unique symbol;
3504
4008
  /** Type-level marker set by count(): make()/create() then return a Collection. */
3505
4009
  interface Many {
@@ -3516,6 +4020,17 @@ interface StateContext {
3516
4020
  }
3517
4021
  type State = Row | ((attributes: Row, context: StateContext) => Row);
3518
4022
  type AnyFactory = Factory<any>;
4023
+ /**
4024
+ * What has() and for() need from a factory: its model, create(), createOne() and state(). A factory of any model,
4025
+ * counted or not, has them; Factory<any> itself would refuse a counted one, whose make(), create() and raw() return
4026
+ * lists.
4027
+ */
4028
+ interface RelatedFactory {
4029
+ readonly model: new () => Model;
4030
+ create(attributes?: Row): Promise<unknown>;
4031
+ createOne(attributes?: Row): Promise<Model>;
4032
+ state(state: State): RelatedFactory;
4033
+ }
3519
4034
  /**
3520
4035
  * A model's factory() typed as its own factory class (Laravel's `@use HasFactory<UserFactory>`): declare it in the
3521
4036
  * model, `declare static factory: HasFactory<UserFactory>` (with `import type`), and User.factory().unverified()
@@ -3526,12 +4041,12 @@ type HasFactory<F> = {
3526
4041
  (count: number, state?: State): F & Many;
3527
4042
  } & (typeof Model)['factory'];
3528
4043
  interface HasRelationship {
3529
- factory: AnyFactory;
4044
+ factory: RelatedFactory;
3530
4045
  relationship: string;
3531
4046
  pivot: Row;
3532
4047
  }
3533
4048
  interface ForRelationship {
3534
- parent: AnyFactory | Model;
4049
+ parent: RelatedFactory | Model;
3535
4050
  relationship: string;
3536
4051
  resolved?: Model;
3537
4052
  }
@@ -3577,9 +4092,9 @@ declare abstract class Factory<M extends Model = Model> {
3577
4092
  /** deleted_at = now, for soft-deleting models. */
3578
4093
  trashed(): this;
3579
4094
  /** Creates related models for each created model: has(Post.factory().count(3)) (relationship default: 'posts'). */
3580
- has(factory: AnyFactory, relationship?: string, pivot?: Row): this;
4095
+ has(factory: RelatedFactory, relationship?: string, pivot?: Row): this;
3581
4096
  /** Sets a belongsTo parent: for(User.factory()) or for(user) (relationship default: 'user'). Created once. */
3582
- for(parent: AnyFactory | Model, relationship?: string): this;
4097
+ for(parent: RelatedFactory | Model, relationship?: string): this;
3583
4098
  afterMaking(callback: (model: M) => unknown): this;
3584
4099
  afterCreating(callback: (model: M) => unknown): this;
3585
4100
  /** The attributes only, without a model (a Row, or a Row[] after count()). */
@@ -3651,7 +4166,7 @@ interface SyncChanges {
3651
4166
  * Many-to-many through a pivot table: post.tags() → belongsToMany(Tag) over post_tag (post_id, tag_id).
3652
4167
  * Each related model carries its pivot row as `tag.pivot` (withPivot() adds columns, withTimestamps() the timestamps).
3653
4168
  */
3654
- declare class BelongsToMany<R extends Model, P extends Model = Model> extends Relation<R, P, Collection<R>> {
4169
+ declare class BelongsToMany<R extends Model, P extends Model = Model> extends Relation<R, P, EloquentCollection<R>> {
3655
4170
  readonly table: string;
3656
4171
  readonly foreignPivotKey: string;
3657
4172
  readonly relatedPivotKey: string;
@@ -3675,7 +4190,7 @@ declare class BelongsToMany<R extends Model, P extends Model = Model> extends Re
3675
4190
  wherePivotIn(column: string, values: readonly unknown[]): this;
3676
4191
  /** Selects the related columns plus the pivot columns (as pivot_*), then moves those onto each model's pivot. */
3677
4192
  runSelect(): Promise<R[]>;
3678
- getResults(): Promise<Collection<R>>;
4193
+ getResults(): Promise<EloquentCollection<R>>;
3679
4194
  initRelation(models: P[], relation: string): P[];
3680
4195
  match(models: P[], results: R[], relation: string): P[];
3681
4196
  getRelationExistenceQuery(query: Builder<R>, _parentQuery: Builder<P>, columns?: ColumnRef[]): Builder<R>;
@@ -3776,8 +4291,8 @@ declare abstract class HasOneOrMany<R extends Model, P extends Model, Result> ex
3776
4291
  }
3777
4292
 
3778
4293
  /** post.comments(): many related rows hold the parent's key. */
3779
- declare class HasMany<R extends Model, P extends Model = Model> extends HasOneOrMany<R, P, Collection<R>> {
3780
- getResults(): Promise<Collection<R>>;
4294
+ declare class HasMany<R extends Model, P extends Model = Model> extends HasOneOrMany<R, P, EloquentCollection<R>> {
4295
+ getResults(): Promise<EloquentCollection<R>>;
3781
4296
  initRelation(models: P[], relation: string): P[];
3782
4297
  match(models: P[], results: R[], relation: string): P[];
3783
4298
  }
@@ -3786,7 +4301,7 @@ declare class HasMany<R extends Model, P extends Model = Model> extends HasOneOr
3786
4301
  * Related rows reached through an intermediate model: country.posts() → hasManyThrough(Post, User):
3787
4302
  * posts join users on users.id = posts.user_id where users.country_id = countries.id.
3788
4303
  */
3789
- declare class HasManyThrough<R extends Model, P extends Model = Model, T extends Model = Model> extends Relation<R, P, Collection<R>> {
4304
+ declare class HasManyThrough<R extends Model, P extends Model = Model, T extends Model = Model> extends Relation<R, P, EloquentCollection<R>> {
3790
4305
  readonly throughParent: T;
3791
4306
  readonly firstKey: string;
3792
4307
  readonly secondKey: string;
@@ -3813,8 +4328,8 @@ declare class HasManyThrough<R extends Model, P extends Model = Model, T extends
3813
4328
  addEagerConstraints(models: P[]): void;
3814
4329
  /** Selects the related columns plus the through key, then moves the key off the attributes. */
3815
4330
  runSelect(): Promise<R[]>;
3816
- getResults(): Promise<Collection<R>>;
3817
- getEager(): Promise<Collection<R>>;
4331
+ getResults(): Promise<EloquentCollection<R>>;
4332
+ getEager(): Promise<EloquentCollection<R>>;
3818
4333
  initRelation(models: P[], relation: string): P[];
3819
4334
  match(models: P[], results: R[], relation: string): P[];
3820
4335
  getRelationExistenceQuery(query: Builder<R>, _parentQuery: Builder<P>, columns?: ColumnRef[]): Builder<R>;
@@ -3925,6 +4440,8 @@ declare class Model implements ModelInstance {
3925
4440
  raw: unknown;
3926
4441
  value: unknown;
3927
4442
  }>;
4443
+ /** Attributes with the hashed cast that were assigned a value since the last save; save() hashes them. */
4444
+ protected pendingHashes: Set<string>;
3928
4445
  constructor();
3929
4446
  /** Runs booting()/booted() once per class, the first time the class is instantiated. */
3930
4447
  static bootIfNotBooted(): void;
@@ -3975,6 +4492,13 @@ declare class Model implements ModelInstance {
3975
4492
  * Observer classes are resolved from the container.
3976
4493
  */
3977
4494
  static observe(...observers: Array<object | (new () => object)>): void;
4495
+ /**
4496
+ * Turns the relation guard on or off: while it is on, reading a property of a relation method as if it were the
4497
+ * related model (`post.author.name`) warns once with how to read the relation. DatabaseServiceProvider turns it on
4498
+ * outside production. Turning it on again forgets which warnings were given.
4499
+ */
4500
+ static warnOnRelationPropertyAccess(enabled?: boolean): void;
4501
+ static warnsOnRelationPropertyAccess(): boolean;
3978
4502
  /** Runs fn with model events off, for this async context only. */
3979
4503
  static withoutEvents<R>(fn: () => R): R;
3980
4504
  /** A new query of this model, with its global scopes. */
@@ -3995,6 +4519,12 @@ declare class Model implements ModelInstance {
3995
4519
  /** Post.whereLike('title', `%${term}%`): case-insensitive unless caseSensitive (see the query builder's whereLike()). */
3996
4520
  static whereLike<C extends typeof Model>(this: C, column: Column<Instance<C>> | Expression, value: string, caseSensitive?: boolean): ModelBuilder<C>;
3997
4521
  static whereNotLike<C extends typeof Model>(this: C, column: Column<Instance<C>> | Expression, value: string, caseSensitive?: boolean): ModelBuilder<C>;
4522
+ /** Post.whereDate('published_at', '2026-01-05'), Post.whereDate('published_at', '<', new Date()). */
4523
+ static whereDate<C extends typeof Model>(this: C, column: Column<Instance<C>> | Expression, ...args: DateWhereArgs): ModelBuilder<C>;
4524
+ static whereTime<C extends typeof Model>(this: C, column: Column<Instance<C>> | Expression, ...args: DateWhereArgs): ModelBuilder<C>;
4525
+ static whereDay<C extends typeof Model>(this: C, column: Column<Instance<C>> | Expression, ...args: DateWhereArgs): ModelBuilder<C>;
4526
+ static whereMonth<C extends typeof Model>(this: C, column: Column<Instance<C>> | Expression, ...args: DateWhereArgs): ModelBuilder<C>;
4527
+ static whereYear<C extends typeof Model>(this: C, column: Column<Instance<C>> | Expression, ...args: DateWhereArgs): ModelBuilder<C>;
3998
4528
  static whereColumn<C extends typeof Model>(this: C, first: Column<Instance<C>>, operatorOrSecond: string, second?: Column<Instance<C>>): ModelBuilder<C>;
3999
4529
  static whereRaw<C extends typeof Model>(this: C, sql: string, bindings?: readonly unknown[]): ModelBuilder<C>;
4000
4530
  static select<C extends typeof Model>(this: C, ...columns: Array<Column<Instance<C>> | Expression>): ModelBuilder<C>;
@@ -4009,6 +4539,13 @@ declare class Model implements ModelInstance {
4009
4539
  /** Eager loads relations: Post.with('author', 'comments.user').get(). */
4010
4540
  static with<C extends typeof Model>(this: C, ...relations: EagerLoadSpec[]): ModelBuilder<C>;
4011
4541
  static withCount<C extends typeof Model>(this: C, ...relations: EagerLoadSpec[]): ModelBuilder<C>;
4542
+ /** Post.withSum('orders', 'price'): adds orders_sum_price. */
4543
+ static withSum<C extends typeof Model>(this: C, relations: EagerLoadSpec | EagerLoadSpec[], column: string | Expression): ModelBuilder<C>;
4544
+ static withAvg<C extends typeof Model>(this: C, relations: EagerLoadSpec | EagerLoadSpec[], column: string | Expression): ModelBuilder<C>;
4545
+ static withMin<C extends typeof Model>(this: C, relations: EagerLoadSpec | EagerLoadSpec[], column: string | Expression): ModelBuilder<C>;
4546
+ static withMax<C extends typeof Model>(this: C, relations: EagerLoadSpec | EagerLoadSpec[], column: string | Expression): ModelBuilder<C>;
4547
+ static withExists<C extends typeof Model>(this: C, ...relations: EagerLoadSpec[]): ModelBuilder<C>;
4548
+ static withAggregate<C extends typeof Model>(this: C, relations: EagerLoadSpec | EagerLoadSpec[], column: string | Expression, fn?: string): ModelBuilder<C>;
4012
4549
  static has<C extends typeof Model>(this: C, relation: string, operator?: string, count?: number): ModelBuilder<C>;
4013
4550
  static whereHas<C extends typeof Model>(this: C, relation: string, callback?: RelationConstraint, operator?: string, count?: number): ModelBuilder<C>;
4014
4551
  static doesntHave<C extends typeof Model>(this: C, relation: string): ModelBuilder<C>;
@@ -4018,11 +4555,11 @@ declare class Model implements ModelInstance {
4018
4555
  /** Soft deletes: only trashed rows. */
4019
4556
  static onlyTrashed<C extends typeof Model>(this: C): ModelBuilder<C>;
4020
4557
  static withoutTrashed<C extends typeof Model>(this: C): ModelBuilder<C>;
4021
- static all<C extends typeof Model>(this: C): Promise<Collection<Instance<C>>>;
4558
+ static all<C extends typeof Model>(this: C): Promise<EloquentCollection<Instance<C>>>;
4022
4559
  static find<C extends typeof Model>(this: C, id: unknown): Promise<Instance<C> | undefined>;
4023
- static findOrFail<C extends typeof Model>(this: C, ids: readonly unknown[]): Promise<Collection<Instance<C>>>;
4560
+ static findOrFail<C extends typeof Model>(this: C, ids: readonly unknown[]): Promise<EloquentCollection<Instance<C>>>;
4024
4561
  static findOrFail<C extends typeof Model>(this: C, id: unknown): Promise<Instance<C>>;
4025
- static findMany<C extends typeof Model>(this: C, ids: readonly unknown[]): Promise<Collection<Instance<C>>>;
4562
+ static findMany<C extends typeof Model>(this: C, ids: readonly unknown[]): Promise<EloquentCollection<Instance<C>>>;
4026
4563
  static first<C extends typeof Model>(this: C): Promise<Instance<C> | undefined>;
4027
4564
  static firstOrFail<C extends typeof Model>(this: C): Promise<Instance<C>>;
4028
4565
  static firstWhere<C extends typeof Model>(this: C, column: Column<Instance<C>> | Expression, operatorOrValue: unknown, value?: unknown): Promise<Instance<C> | undefined>;
@@ -4032,8 +4569,8 @@ declare class Model implements ModelInstance {
4032
4569
  static paginate<C extends typeof Model>(this: C, perPage?: number, columns?: string[], pageName?: string, page?: number): Promise<LengthAwarePaginator<Instance<C>>>;
4033
4570
  static simplePaginate<C extends typeof Model>(this: C, perPage?: number, columns?: string[], pageName?: string, page?: number): Promise<Paginator<Instance<C>>>;
4034
4571
  static cursorPaginate<C extends typeof Model>(this: C, perPage?: number, columns?: string[], cursorName?: string, cursor?: Cursor | string): Promise<CursorPaginator<Instance<C>>>;
4035
- static chunk<C extends typeof Model>(this: C, count: number, callback: (models: Collection<Instance<C>>, page: number) => unknown): Promise<boolean>;
4036
- static chunkById<C extends typeof Model>(this: C, count: number, callback: (models: Collection<Instance<C>>, page: number) => unknown): Promise<boolean>;
4572
+ static chunk<C extends typeof Model>(this: C, count: number, callback: (models: EloquentCollection<Instance<C>>, page: number) => unknown): Promise<boolean>;
4573
+ static chunkById<C extends typeof Model>(this: C, count: number, callback: (models: EloquentCollection<Instance<C>>, page: number) => unknown): Promise<boolean>;
4037
4574
  static each<C extends typeof Model>(this: C, callback: (model: Instance<C>, index: number) => unknown, count?: number): Promise<boolean>;
4038
4575
  static lazy<C extends typeof Model>(this: C, chunkSize?: number): LazyCollection<Instance<C>>;
4039
4576
  static lazyById<C extends typeof Model>(this: C, chunkSize?: number): LazyCollection<Instance<C>>;
@@ -4077,6 +4614,8 @@ declare class Model implements ModelInstance {
4077
4614
  hasSetMutator(key: string): boolean;
4078
4615
  /** Every cast, including the implied ones: the incrementing key (int) and the timestamp columns (datetime). */
4079
4616
  getCasts(): Record<string, CastDefinition>;
4617
+ /** Adds casts to this instance only (Laravel's mergeCasts()); withCasts() on a query does it for each result. */
4618
+ mergeCasts(casts: Readonly<Record<string, CastDefinition>>): this;
4080
4619
  hasCast(key: string, types?: string[]): boolean;
4081
4620
  /** The stored attributes, with in-place changes to json casts written back. */
4082
4621
  getAttributes(): Row;
@@ -4174,6 +4713,14 @@ declare class Model implements ModelInstance {
4174
4713
  * runs no query at all. Returns false when a saving/creating/updating listener cancels.
4175
4714
  */
4176
4715
  save(): Promise<boolean>;
4716
+ /**
4717
+ * Laravel's hashed cast (castAttributeAsHashedString()), run when the model is saved because the Hasher is
4718
+ * asynchronous: each newly assigned value is hashed before the saving event, so every listener sees the hash, and
4719
+ * again just before the write (after the creating or updating event), so a value a listener assigns is hashed too.
4720
+ * A value that is already a hash is kept when it matches the configured algorithm and options, and refused
4721
+ * otherwise. Only strings and numbers are hashed (null stays null); any other value is refused.
4722
+ */
4723
+ protected hashPendingAttributes(): Promise<void>;
4177
4724
  /** Fills and saves an existing model. */
4178
4725
  update(attributes?: Row): Promise<boolean>;
4179
4726
  /**
@@ -4274,7 +4821,7 @@ declare class Model implements ModelInstance {
4274
4821
  getRelationInstance(name: string): Relation;
4275
4822
  /**
4276
4823
  * A loaded relation, typed from the relation method: post.getRelation('author') is User | null,
4277
- * post.getRelation('comments') is Collection<Comment>. Throws RelationNotLoadedError when it isn't loaded
4824
+ * post.getRelation('comments') is EloquentCollection<Comment>. Throws RelationNotLoadedError when it isn't loaded
4278
4825
  * (JavaScript can't lazy-load synchronously: use with(), load() or post.comments().get()).
4279
4826
  */
4280
4827
  getRelation<K extends RelationNames<this>>(name: K): RelationValue<this, K>;
@@ -4284,6 +4831,20 @@ declare class Model implements ModelInstance {
4284
4831
  loadMissing(...relations: string[]): Promise<this>;
4285
4832
  /** Loads <relation>_count attributes: await post.loadCount('comments'). */
4286
4833
  loadCount(...relations: EagerLoadSpec[]): Promise<this>;
4834
+ /** Loads an aggregate of a relation as an attribute (Laravel's loadAggregate()): see withAggregate(). */
4835
+ loadAggregate(relations: EagerLoadSpec | EagerLoadSpec[], column: string | Expression, fn?: string): Promise<this>;
4836
+ /** Loads <relation>_sum_<column>: await user.loadSum('orders', 'price'). */
4837
+ loadSum(relations: EagerLoadSpec | EagerLoadSpec[], column: string | Expression): Promise<this>;
4838
+ loadAvg(relations: EagerLoadSpec | EagerLoadSpec[], column: string | Expression): Promise<this>;
4839
+ loadMin(relations: EagerLoadSpec | EagerLoadSpec[], column: string | Expression): Promise<this>;
4840
+ loadMax(relations: EagerLoadSpec | EagerLoadSpec[], column: string | Expression): Promise<this>;
4841
+ /** Loads a boolean <relation>_exists. */
4842
+ loadExists(...relations: EagerLoadSpec[]): Promise<this>;
4843
+ /**
4844
+ * The collection queries of this model return (Laravel's newCollection()): an EloquentCollection. Override it to
4845
+ * return a subclass with your own methods.
4846
+ */
4847
+ newCollection<T extends Model>(this: T, models?: T[]): EloquentCollection<T>;
4287
4848
  /** Stores a loaded relation (eager loading and load() use this). */
4288
4849
  setRelation(name: string, value: unknown): this;
4289
4850
  relationLoaded(name: string): boolean;
@@ -4361,13 +4922,15 @@ declare class DatabaseNotification extends DatabaseNotification_base implements
4361
4922
  markAsUnread(): Promise<void>;
4362
4923
  read(): boolean;
4363
4924
  unread(): boolean;
4925
+ /** Queries of notifications return a DatabaseNotificationCollection (markAsRead() on all of them). */
4926
+ newCollection<T extends Model>(this: T, models?: T[]): EloquentCollection<T>;
4364
4927
  /** `query.read()`: only read notifications. */
4365
4928
  static scopeRead(query: Builder<DatabaseNotification>): Builder<DatabaseNotification>;
4366
4929
  /** `query.unread()`: only unread notifications. */
4367
4930
  static scopeUnread(query: Builder<DatabaseNotification>): Builder<DatabaseNotification>;
4368
4931
  }
4369
4932
  /** Laravel's DatabaseNotificationCollection: what `await user.notifications().get()` returns. */
4370
- declare class DatabaseNotificationCollection extends Collection<DatabaseNotification> {
4933
+ declare class DatabaseNotificationCollection extends EloquentCollection<DatabaseNotification> {
4371
4934
  /** Marks every notification as read (one save each, as in Laravel). */
4372
4935
  markAsRead(): Promise<void>;
4373
4936
  /** Marks every notification as unread. */
@@ -4549,6 +5112,14 @@ declare class Migrator {
4549
5112
  private rollDown;
4550
5113
  /** Runs up/down on the migration's connection (made the default meanwhile), in a transaction where DDL allows it. */
4551
5114
  private runMigration;
5115
+ /**
5116
+ * SQLite's order for a migration in a transaction: foreign keys off before the transaction (SQLite ignores the pragma
5117
+ * inside one, and a table rebuild would otherwise run the ON DELETE actions of the tables that reference it), the
5118
+ * migration, a foreign key check before the commit (rows that break a key fail the migration), then foreign keys back
5119
+ * on. A migration outside a transaction runs with foreign keys as they are, so its ON DELETE and ON UPDATE actions
5120
+ * run; a table rebuild in it turns them off around itself and checks the table.
5121
+ */
5122
+ private runOnSqlite;
4552
5123
  }
4553
5124
 
4554
5125
  type SeederClass = new () => Seeder;
@@ -4781,34 +5352,38 @@ declare class InvalidRuleParameterError extends Error implements OrielError {
4781
5352
  constructor(rule: string, parameter: string, reason: string);
4782
5353
  }
4783
5354
 
5355
+ /** The data a FormRequest's validate() returns, typed from its rules(). */
5356
+ type ValidatedData<F extends FormRequest> = InferValidatedType<Awaited<ReturnType<F['rules']>>>;
4784
5357
  /**
4785
5358
  * Mirrors Illuminate\Foundation\Http\FormRequest, minus dependency injection by type (Oriel resolves the current
4786
5359
  * request and the ValidationFactory through inject(), never through constructor parameters — see spec §3 rule 5).
4787
5360
  * A subclass only has to implement rules(); authorize()/messages()/attributes() default to Laravel's own defaults.
4788
5361
  */
4789
5362
  declare abstract class FormRequest {
4790
- abstract rules(): Rules;
5363
+ /** May be async, to await something first: `async rules() { const user = await request().user<User>() … }`. */
5364
+ abstract rules(): Rules | Promise<Rules>;
4791
5365
  authorize(): boolean | Promise<boolean>;
4792
5366
  messages(): Record<string, string>;
4793
5367
  attributes(): Record<string, string>;
4794
5368
  /**
4795
5369
  * `const data = await StorePostRequest.validate()` (spec §4.3). Resolves the current request and the
4796
5370
  * ValidationFactory from the active container, runs authorize() first (throwing AuthorizationErrorImpl if it
4797
- * returns false), then validates request.all() against rules()/messages()/attributes() and returns the typed
4798
- * validated data (or throws the 422 ValidationError — see ValidatorImpl.validated()).
5371
+ * returns false), then validates request.all() against rules()/messages()/attributes() and returns the validated
5372
+ * data (or throws the 422 ValidationError — see ValidatorImpl.validated()). The data is typed from rules(): write
5373
+ * it without a return type and with `as const` (`return { title: 'required|string' } as const`), so its rule
5374
+ * strings keep their text; a rules() typed `Rules` gives `Record<string, unknown>`.
4799
5375
  */
4800
- static validate<T = Record<string, unknown>>(this: new () => FormRequest): Promise<T>;
5376
+ static validate<F extends FormRequest>(this: new () => F): Promise<ValidatedData<F>>;
4801
5377
  }
4802
5378
 
4803
- /** Humanizes a (possibly dotted) attribute key, e.g. "items.0.product_name" -> "items.0.product name". */
5379
+ /** Humanizes a (possibly dotted) attribute key, e.g. "items.0.product_name" -> "items.0.product name" ("colors.*" stays). */
4804
5380
  declare function defaultAttributeName(key: string): string;
4805
5381
  declare function applyReplacements(template: string, replacements: Record<string, string>): string;
4806
- /** Laravel's English lang/en/validation.php, reproduced as closely as possible (see plan Notes/assumptions). */
5382
+ /** Laravel's English lang/en/validation.php, reproduced as closely as possible. */
4807
5383
  declare const DEFAULT_MESSAGES: Record<string, string>;
4808
5384
 
4809
5385
  declare class MessageBagImpl implements MessageBag {
4810
5386
  private readonly items;
4811
- /** Not part of the MessageBag contract — used internally by ValidatorImpl and by after() hooks. */
4812
5387
  add(key: string, message: string): void;
4813
5388
  has(key: string): boolean;
4814
5389
  first(key?: string): string | undefined;
@@ -4830,6 +5405,17 @@ interface RuleContext {
4830
5405
  data: Record<string, unknown>;
4831
5406
  /** Every named rule attached to this field (for size-type resolution: numeric/array/file/string). */
4832
5407
  ruleNames: string[];
5408
+ /** The rule key as written, e.g. "items.*.email" (distinct reads every row of it). */
5409
+ pattern?: string;
5410
+ /**
5411
+ * What the rules keep for one validation pass, such as every row a wildcard names: each pass starts with an empty
5412
+ * one, so nothing outlives the data it was read from. Absent when a rule runs on its own.
5413
+ */
5414
+ cache?: Map<string, unknown>;
5415
+ /** The parameters of rule `name` on `field` (a concrete path), or undefined when that field has no such rule. */
5416
+ getRule?(field: string, name: string): string[] | undefined;
5417
+ /** How a message names `field`: its custom attribute, else the humanized key. */
5418
+ displayName?(field: string): string;
4833
5419
  }
4834
5420
  interface BuiltinRule {
4835
5421
  validate(ctx: RuleContext): boolean | Promise<boolean>;
@@ -4843,6 +5429,11 @@ interface BuiltinRule {
4843
5429
  message?: string;
4844
5430
  /** Runs even when the value is missing, blank, or null under nullable (the required* family, and accepted); a failure stops the field. */
4845
5431
  implicit?: boolean;
5432
+ /**
5433
+ * An exclude rule (`exclude`, `exclude_if`, …): it always runs, and when validate() returns false the field and its
5434
+ * children are skipped from then on and left out of the validated data, with no message.
5435
+ */
5436
+ excludes?: boolean;
4846
5437
  }
4847
5438
  type ParsedRule = {
4848
5439
  kind: 'named';
@@ -4852,8 +5443,18 @@ type ParsedRule = {
4852
5443
  kind: 'object';
4853
5444
  rule: ValidationRule;
4854
5445
  };
4855
- declare function parseRuleSpec(spec: string | ReadonlyArray<string | ValidationRule>): ParsedRule[];
4856
- /** Laravel's definition of "empty" for the required family: null, undefined, '' and []. false and 0 are NOT empty. */
5446
+ /**
5447
+ * A rule object that stands for string rules (Rule.requiredIf(), Rule.when(), Rule.array(), …), as Laravel's
5448
+ * ValidationRuleParser reads them: the rules expandRules() returns, given the data, take its place.
5449
+ */
5450
+ interface ExpandingRule extends ValidationRule {
5451
+ expandRules(data: Record<string, unknown>): string | ReadonlyArray<string | ValidationRule>;
5452
+ }
5453
+ declare function parseRuleSpec(spec: string | ReadonlyArray<string | ValidationRule>, data?: Record<string, unknown>): ParsedRule[];
5454
+ /**
5455
+ * Laravel's definition of "empty" for the required family (validateRequired()): null, undefined, text that is blank
5456
+ * once trimmed, an empty array and an empty plain object (a JSON object is a PHP array). false and 0 are NOT empty.
5457
+ */
4857
5458
  declare function isEmptyValue(value: unknown): boolean;
4858
5459
  /** Duck-types Contracts/Http's UploadedFile without importing @orieljs/http. */
4859
5460
  declare function isUploadedFileLike(value: unknown): value is {
@@ -4866,8 +5467,8 @@ declare function isUploadedFileLike(value: unknown): value is {
4866
5467
  /**
4867
5468
  * Expands a `*`-wildcard rule pattern (e.g. "items.*.name") into every concrete path present in `data`
4868
5469
  * (e.g. ["items.0.name", "items.1.name"]). A pattern with no `*` is returned unchanged. A `*` segment whose
4869
- * container is missing, not an array and not a plain object expands to nothing for that branch (Review Focus #4:
4870
- * every reported error is keyed by a concrete path, never the literal pattern). Object keys in UNSAFE_KEYS are
5470
+ * container is missing, not an array and not a plain object expands to nothing for that branch, so every reported
5471
+ * error is keyed by a concrete path, never the literal pattern. Object keys in UNSAFE_KEYS are
4871
5472
  * treated as absent, so a JSON body like {"items":{"__proto__":{...}}} never yields a path through the prototype.
4872
5473
  */
4873
5474
  declare function expandWildcardKeys(pattern: string, data: Record<string, unknown>): string[];
@@ -4881,8 +5482,14 @@ declare const builtinRules: Record<string, BuiltinRule>;
4881
5482
  * Rule.password() returns the application default (PasswordRule.defaults()). (Laravel's uncompromised() is not
4882
5483
  * ported: it calls an outside service.)
4883
5484
  */
4884
- declare class PasswordRule implements ValidationRule {
5485
+ declare class PasswordRule implements TypedValidationRule<{
5486
+ value: string;
5487
+ }> {
4885
5488
  #private;
5489
+ /** A passing value is a string (for the validated data's type); never set at run time. */
5490
+ readonly __typing?: {
5491
+ value: string;
5492
+ };
4886
5493
  constructor(min?: number);
4887
5494
  /** A password rule of at least `size` characters: PasswordRule.min(12).mixedCase(). */
4888
5495
  static min(size: number): PasswordRule;
@@ -4902,7 +5509,7 @@ declare class PasswordRule implements ValidationRule {
4902
5509
  numbers(): this;
4903
5510
  /** At least one symbol (punctuation, a symbol or a space). */
4904
5511
  symbols(): this;
4905
- validate(attribute: string, value: unknown, fail: (message: string) => void): void;
5512
+ validate(_attribute: string, value: unknown, fail: (message: string) => void): void;
4906
5513
  }
4907
5514
 
4908
5515
  /**
@@ -4911,17 +5518,121 @@ declare class PasswordRule implements ValidationRule {
4911
5518
  * ("email.unique", "items.*.email.unique", "unique"), custom attributes, then the default text. Called directly
4912
5519
  * as a plain ValidationRule, validate() fails with the default English message.
4913
5520
  */
4914
- declare abstract class BuiltinRuleObject implements ValidationRule {
5521
+ declare abstract class BuiltinRuleObject<T extends RuleTyping = Record<never, never>> implements TypedValidationRule<T> {
4915
5522
  abstract readonly ruleName: string;
4916
- abstract passes(attribute: string, value: unknown, data: Record<string, unknown>, expandedFromWildcard?: boolean): boolean | Promise<boolean>;
5523
+ /** What a passing value is, for the validated data's type (`T`); never set at run time. */
5524
+ readonly __typing?: T;
5525
+ /** `ruleNames`: the field's named rules, when it runs inside a Validator (`Rule.in()` reads `array`). */
5526
+ abstract passes(attribute: string, value: unknown, data: Record<string, unknown>, expandedFromWildcard?: boolean, ruleNames?: readonly string[]): boolean | Promise<boolean>;
5527
+ /** The parameters its message shows (`:values` of Rule.doesntContain()), as the string rule's would be. */
5528
+ messageParameters(): string[];
4917
5529
  validate(attribute: string, value: unknown, fail: (message: string) => void, data: Record<string, unknown>, expandedFromWildcard?: boolean): Promise<void>;
4918
5530
  }
4919
- declare class InRule extends BuiltinRuleObject {
5531
+ /**
5532
+ * What `Rule.in(values)` lets through. A list the compiler only knows as `string[]` says nothing: any value whose text
5533
+ * is listed passes (the number 1 for '1'), so `string` would be too narrow. A rule string known only as `string` is
5534
+ * treated the same way.
5535
+ */
5536
+ type InTyping<V> = string extends V ? Record<never, never> : {
5537
+ value: InValue<V>;
5538
+ each: InValue<V>;
5539
+ };
5540
+ declare class InRule<V> extends BuiltinRuleObject<InTyping<V>> {
4920
5541
  private readonly values;
4921
5542
  readonly ruleName = "in";
5543
+ constructor(values: readonly V[]);
5544
+ passes(_attribute: string, value: unknown, _data?: Record<string, unknown>, _expanded?: boolean, ruleNames?: readonly string[]): boolean;
5545
+ }
5546
+ declare class NotInRule extends BuiltinRuleObject {
5547
+ private readonly values;
5548
+ readonly ruleName = "not_in";
4922
5549
  constructor(values: readonly unknown[]);
5550
+ passes(_attribute: string, value: unknown, _data?: Record<string, unknown>, _expanded?: boolean, ruleNames?: readonly string[]): boolean;
5551
+ }
5552
+ /** A TypeScript enum, or an `as const` object of string and number values. */
5553
+ type EnumLike = Record<string, string | number>;
5554
+ /**
5555
+ * Laravel's Rule::enum(): one of the enum's values; for a numeric enum, its number or exactly the text of it (a form
5556
+ * sends text: `'1'`, not `'1.0'` or `'01'`). only() and except() narrow the values.
5557
+ */
5558
+ declare class EnumRule<E extends EnumLike> extends BuiltinRuleObject<{
5559
+ value: InValue<E[keyof E]>;
5560
+ }> {
5561
+ #private;
5562
+ private readonly type;
5563
+ readonly ruleName = "enum";
5564
+ constructor(type: E);
5565
+ only(values: E[keyof E] | ReadonlyArray<E[keyof E]>): this;
5566
+ except(values: E[keyof E] | ReadonlyArray<E[keyof E]>): this;
4923
5567
  passes(_attribute: string, value: unknown): boolean;
4924
5568
  }
5569
+ /** Laravel's Rule::contains() and Rule::doesntContain(): every value is an item of the array, or none is. */
5570
+ declare class ContainsRule extends BuiltinRuleObject<{
5571
+ value: unknown[];
5572
+ }> {
5573
+ readonly ruleName: 'contains' | 'doesnt_contain';
5574
+ private readonly values;
5575
+ constructor(ruleName: 'contains' | 'doesnt_contain', values: readonly unknown[]);
5576
+ passes(_attribute: string, value: unknown): boolean;
5577
+ messageParameters(): string[];
5578
+ }
5579
+ /** Rules for the field: a rule string, a list, or a callback given the data that returns one. */
5580
+ type RuleSet = string | ReadonlyArray<string | ValidationRule> | ((data: Record<string, unknown>) => string | ReadonlyArray<string | ValidationRule>);
5581
+ /**
5582
+ * Base for the builders that stand for string rules (Laravel's RequiredIf, ConditionalRules, ArrayRule, Dimensions):
5583
+ * the Validator puts the rules expandRules() returns in their place, so they run only inside a Validator.
5584
+ */
5585
+ declare abstract class ExpandingRuleObject<T extends RuleTyping = Record<never, never>> implements ExpandingRule, TypedValidationRule<T> {
5586
+ readonly __typing?: T;
5587
+ abstract expandRules(data: Record<string, unknown>): string | ReadonlyArray<string | ValidationRule>;
5588
+ validate(): never;
5589
+ }
5590
+ /** Rule.requiredIf(), Rule.excludeIf(), Rule.prohibitedIf(): the rule when the condition holds, else nothing. */
5591
+ declare class ConditionalRule<T extends RuleTyping = Record<never, never>> extends ExpandingRuleObject<T> {
5592
+ private readonly rule;
5593
+ private readonly condition;
5594
+ constructor(rule: 'required' | 'exclude' | 'prohibited', condition: boolean | (() => boolean));
5595
+ expandRules(): string;
5596
+ }
5597
+ /** Laravel's ConditionalRules (Rule.when() and Rule.unless()): one set of rules or the other, chosen from the data. */
5598
+ declare class ConditionalRules extends ExpandingRuleObject {
5599
+ private readonly condition;
5600
+ private readonly rules;
5601
+ private readonly defaultRules;
5602
+ private readonly negate;
5603
+ constructor(condition: boolean | ((data: Record<string, unknown>) => boolean), rules: RuleSet, defaultRules: RuleSet, negate?: boolean);
5604
+ expandRules(data: Record<string, unknown>): string | ReadonlyArray<string | ValidationRule>;
5605
+ }
5606
+ /** Laravel's Rule::array(): `array`, or `array:a,b` (an object whose keys are among those named). */
5607
+ declare class ArrayRule<K extends string> extends ExpandingRuleObject<{
5608
+ value: [K] extends [never] ? unknown[] : {
5609
+ [P in K]?: unknown;
5610
+ };
5611
+ }> {
5612
+ private readonly keys;
5613
+ constructor(keys: readonly K[]);
5614
+ expandRules(): string;
5615
+ }
5616
+ type DimensionConstraints = Partial<Record<'width' | 'height' | 'min_width' | 'min_height' | 'max_width' | 'max_height' | 'ratio', number>>;
5617
+ /** Laravel's Rule::dimensions(): the dimensions rule, from an object or fluently (`.maxWidth(1000).ratio(3 / 2)`). */
5618
+ declare class DimensionsRule extends ExpandingRuleObject<{
5619
+ value: UploadedFile;
5620
+ }> {
5621
+ #private;
5622
+ constructor(constraints: DimensionConstraints);
5623
+ width(pixels: number): this;
5624
+ height(pixels: number): this;
5625
+ minWidth(pixels: number): this;
5626
+ minHeight(pixels: number): this;
5627
+ maxWidth(pixels: number): this;
5628
+ maxHeight(pixels: number): this;
5629
+ /** Width over height: `ratio(3 / 2)`. */
5630
+ ratio(ratio: number): this;
5631
+ /** `dimensions:max_width=1000,ratio=1.5`, Laravel's __toString(). */
5632
+ toString(): string;
5633
+ expandRules(): string;
5634
+ private set;
5635
+ }
4925
5636
  declare class UniqueRule extends BuiltinRuleObject {
4926
5637
  private readonly table;
4927
5638
  private readonly column?;
@@ -4948,34 +5659,38 @@ declare class ExistsRule extends BuiltinRuleObject {
4948
5659
  }
4949
5660
  /** Fluent rule-object builders, for when a plain string rule can't express what's needed (e.g. .ignore()). */
4950
5661
  declare const Rule: {
4951
- in: (values: readonly unknown[]) => InRule;
5662
+ /** One of `values`, compared as text (as `in:a,b`); typed as those values: `Rule.in(['draft', 'publish'])`. */
5663
+ in: <const V extends readonly unknown[]>(values: V) => InRule<V[number]>;
5664
+ /** None of `values`, compared as text (as `not_in:a,b`). */
5665
+ notIn: (values: readonly unknown[]) => NotInRule;
5666
+ /** One of a TypeScript enum's values (or an `as const` object's): `Rule.enum(Status)`, `.only([…])`, `.except([…])`. */
5667
+ enum: <E extends EnumLike>(type: E) => EnumRule<E>;
5668
+ /** An array holding every one of `values`. */
5669
+ contains: (values: readonly unknown[]) => ContainsRule;
5670
+ /** An array holding none of `values`. */
5671
+ doesntContain: (values: readonly unknown[]) => ContainsRule;
5672
+ /** `required` when the condition (or the callback) holds. */
5673
+ requiredIf: (condition: boolean | (() => boolean)) => ConditionalRule;
5674
+ /** `exclude` when the condition (or the callback) holds; the key is optional, as `exclude_if` makes it. */
5675
+ excludeIf: (condition: boolean | (() => boolean)) => ConditionalRule<{
5676
+ presence: "optional";
5677
+ }>;
5678
+ /** `prohibited` when the condition (or the callback) holds. */
5679
+ prohibitedIf: (condition: boolean | (() => boolean)) => ConditionalRule;
5680
+ /** `rules` when the condition (or the callback, given the data) holds, else `defaultRules`. */
5681
+ when: (condition: boolean | ((data: Record<string, unknown>) => boolean), rules: RuleSet, defaultRules?: RuleSet) => ConditionalRules;
5682
+ /** `rules` unless the condition (or the callback, given the data) holds, else `defaultRules`. */
5683
+ unless: (condition: boolean | ((data: Record<string, unknown>) => boolean), rules: RuleSet, defaultRules?: RuleSet) => ConditionalRules;
5684
+ /** `array`, or with keys `array:name,email` (an object whose keys are among those named). */
5685
+ array: <const K extends string = never>(keys?: readonly K[]) => ArrayRule<K>;
5686
+ /** The dimensions rule: `Rule.dimensions().maxWidth(1000).ratio(3 / 2)`, or `Rule.dimensions({ min_width: 100 })`. */
5687
+ dimensions: (constraints?: DimensionConstraints) => DimensionsRule;
4952
5688
  unique: (table: string, column?: string) => UniqueRule;
4953
5689
  exists: (table: string, column?: string) => ExistsRule;
4954
5690
  /** Laravel's Password::defaults(): the application's password rule (at least 8 characters unless PasswordRule.defaults() changed it). */
4955
5691
  password: () => PasswordRule;
4956
5692
  };
4957
5693
 
4958
- /** See Task 9's writeup in the plan for exactly what this does and doesn't infer. */
4959
- type SplitPipe<S extends string> = S extends `${infer Head}|${infer Tail}` ? Head | SplitPipe<Tail> : S;
4960
- type RuleName<T extends string> = T extends `${infer Name}:${string}` ? Name : T;
4961
- type Names<S extends string> = RuleName<SplitPipe<S>>;
4962
- type BaseType<S extends string> = 'array' extends Names<S> ? unknown[] : 'boolean' extends Names<S> ? boolean : 'integer' extends Names<S> ? number : 'numeric' extends Names<S> ? number : 'email' extends Names<S> ? string : 'url' extends Names<S> ? string : 'uuid' extends Names<S> ? string : 'date' extends Names<S> ? string : 'string' extends Names<S> ? string : unknown;
4963
- /**
4964
- * The inferred type for one rule string, e.g. 'nullable|integer' -> number | null. A non-literal `string` (a rules
4965
- * object declared without `as const`) carries no rule names to read, so it infers unknown: without this guard every
4966
- * `'x' extends string` check would match and the result would wrongly be `unknown[] | null`.
4967
- */
4968
- type InferRuleType<S extends string> = string extends S ? unknown : 'nullable' extends Names<S> ? BaseType<S> | null : BaseType<S>;
4969
- /**
4970
- * Best-effort: applies InferRuleType to every string-valued rule; array-form (mixed string/object) rules -> unknown.
4971
- * Strips `readonly` (via `-readonly`) so a `Rules` object declared `as const` (the common way to get literal rule
4972
- * strings for inference — see the Task 9 type test) still produces a plain, mutable validated-data shape, not a
4973
- * readonly one; a mapped type otherwise carries the source's readonly modifier over by default.
4974
- */
4975
- type InferValidatedType<R> = {
4976
- -readonly [K in keyof R]: R[K] extends string ? InferRuleType<R[K]> : unknown;
4977
- };
4978
-
4979
5694
  /**
4980
5695
  * Runs each field's rules the way Laravel's Validator does:
4981
5696
  * - a missing key, or a string that is blank after trimming, only runs implicit rules (the required* family and
@@ -4985,7 +5700,7 @@ type InferValidatedType<R> = {
4985
5700
  * - `sometimes` skips a missing field entirely;
4986
5701
  * - a field stops validating after its first failure under `bail`, or after any implicit rule fails.
4987
5702
  */
4988
- declare class ValidatorImpl implements Validator$1 {
5703
+ declare class ValidatorImpl<R extends Rules = Rules> implements Validator$1<R> {
4989
5704
  private readonly data;
4990
5705
  private readonly rules;
4991
5706
  private readonly customMessages;
@@ -4995,16 +5710,40 @@ declare class ValidatorImpl implements Validator$1 {
4995
5710
  private bag;
4996
5711
  private ranPromise;
4997
5712
  private readonly afterCallbacks;
4998
- constructor(data: Record<string, unknown>, rules: Rules, customMessages: Record<string, string>, customAttributes: Record<string, string>, registry: Record<string, BuiltinRule>, errorBagName?: string);
5713
+ private parsedRules;
5714
+ /** The fields an exclude rule took out (with their children). */
5715
+ private readonly excluded;
5716
+ /** The same fields as a tree of segment runs from the root, so a lookup reads the field once. */
5717
+ private readonly excludedRuns;
5718
+ /** What the rules keep while one pass runs (RuleContext.cache); a new pass starts with a new one. */
5719
+ private cache;
5720
+ constructor(data: Record<string, unknown>, rules: R, customMessages: Record<string, string>, customAttributes: Record<string, string>, registry: Record<string, BuiltinRule>, errorBagName?: string);
4999
5721
  after(callback: (validator: Validator$1) => void | Promise<void>): this;
5000
- /** Not part of the Validator contract — lets an after() hook add a failure (MessageBag itself is read-only). */
5722
+ /** Lets an after() hook add a failure. */
5001
5723
  fail(field: string, message: string): void;
5002
5724
  passes(): Promise<boolean>;
5003
5725
  fails(): Promise<boolean>;
5004
5726
  errors(): MessageBagImpl;
5005
- validated<T = Record<string, unknown>>(): Promise<T>;
5727
+ validated<T = InferValidatedType<R>>(): Promise<T>;
5728
+ /** Takes the field (with its children) out of validation and of the validated data. */
5729
+ private exclude;
5730
+ /**
5731
+ * Laravel's shouldBeExcluded(): the field, or one of its parents, was taken out by an exclude rule. The field's
5732
+ * segments are followed from the root (so `user` takes out `user.name`, not `username`) and each is read once,
5733
+ * however many fields were excluded and however many dots the field holds.
5734
+ */
5735
+ private isExcluded;
5006
5736
  private fieldsFor;
5737
+ private parsed;
5738
+ /** The rule key a concrete field falls under: itself, else the first wildcard key that matches it. */
5739
+ private patternOf;
5740
+ /** Laravel's getRule(): the parameters of rule `name` on `field`, or undefined when the field has no such rule. */
5741
+ private ruleParameters;
5742
+ /** Laravel's getDisplayableAttribute(): a custom attribute for the field or its rule key, else the humanized key. */
5743
+ private displayName;
5744
+ private context;
5007
5745
  private run;
5746
+ private passesExcludeRule;
5008
5747
  private runRule;
5009
5748
  /** Custom message (concrete field, then wildcard pattern, then rule name) or the default, with :attribute filled. */
5010
5749
  private failureMessage;
@@ -5012,7 +5751,7 @@ declare class ValidatorImpl implements Validator$1 {
5012
5751
 
5013
5752
  declare class ValidationFactoryImpl implements ValidationFactory {
5014
5753
  private readonly extended;
5015
- make(data: Record<string, unknown>, rules: Rules, messages?: Record<string, string>, attributes?: Record<string, string>): ValidatorImpl;
5754
+ make<const R extends Rules>(data: Record<string, unknown>, rules: R, messages?: Record<string, string>, attributes?: Record<string, string>): ValidatorImpl<R>;
5016
5755
  extend(name: string, callback: RuleCallback, message?: string): void;
5017
5756
  }
5018
5757
 
@@ -5231,7 +5970,7 @@ declare class CookieJar implements CookieJar$1 {
5231
5970
  #private;
5232
5971
  constructor(defaults?: CookieDefaults);
5233
5972
  make(name: string, value: string, minutes?: number, options?: CookieOptions): Cookie$1;
5234
- /** Five years, like Laravel. */
5973
+ /** 400 days, as in Laravel: the longest lifetime browsers keep a cookie. */
5235
5974
  forever(name: string, value: string, options?: CookieOptions): Cookie$1;
5236
5975
  /** An expired cookie that makes the browser delete it. */
5237
5976
  forget(name: string, options?: CookieOptions): Cookie$1;
@@ -5516,12 +6255,13 @@ declare class VerifyCsrfToken implements Middleware {
5516
6255
  }
5517
6256
 
5518
6257
  /**
5519
- * A read-only MessageBag over one bag of the flashed validation errors. Http flashes
6258
+ * A MessageBag over one bag of the flashed validation errors (add() changes this bag, not the session). Http flashes
5520
6259
  * `errors: { [bag]: { field: string[] } }`; views read them with `errors().first('email')`.
5521
6260
  */
5522
6261
  declare class SessionMessageBag implements MessageBag {
5523
6262
  #private;
5524
6263
  constructor(messages?: Record<string, string[]>);
6264
+ add(key: string, message: string): void;
5525
6265
  has(key: string): boolean;
5526
6266
  first(key?: string): string | undefined;
5527
6267
  get(key: string): string[];
@@ -5695,7 +6435,7 @@ declare class SendEmailVerificationNotification {
5695
6435
  */
5696
6436
  declare class EmailVerificationRequest {
5697
6437
  static validate(): Promise<Record<string, never>>;
5698
- authorize(): boolean;
6438
+ authorize(): Promise<boolean>;
5699
6439
  rules(): Record<string, never>;
5700
6440
  /** Marks the signed-in user's email as verified and fires Verified, unless it already was. */
5701
6441
  fulfill(): Promise<void>;
@@ -5785,8 +6525,6 @@ declare class SessionGuard implements StatefulGuard {
5785
6525
  private readonly options;
5786
6526
  constructor(name: string, provider: UserProvider, container: Container$1, options?: SessionGuardOptions);
5787
6527
  user<T extends Authenticatable = Authenticatable>(): Promise<T | undefined>;
5788
- /** The user already resolved in this request, without touching the provider (used by request.user()). */
5789
- currentUser(): Authenticatable | undefined;
5790
6528
  id(): Promise<unknown>;
5791
6529
  check(): Promise<boolean>;
5792
6530
  guest(): Promise<boolean>;
@@ -5931,8 +6669,6 @@ declare class TokenGuard implements Guard {
5931
6669
  private readonly options;
5932
6670
  constructor(name: string, provider: UserProvider, container: Container$1, tokens: TokenRepository, options?: TokenGuardOptions);
5933
6671
  user<T extends Authenticatable = Authenticatable>(): Promise<T | undefined>;
5934
- /** The user already resolved in this request (used by request.user()). */
5935
- currentUser(): Authenticatable | undefined;
5936
6672
  /** The token the request authenticated with. */
5937
6673
  currentAccessToken(): PersonalAccessToken | undefined;
5938
6674
  id(): Promise<unknown>;
@@ -5950,7 +6686,7 @@ declare class TokenGuard implements Guard {
5950
6686
  * sessions in one file.
5951
6687
  */
5952
6688
  declare const USERS_TABLE_MIGRATION = "import { Migration, Schema } from '@orieljs/framework'\n\nexport default class extends Migration {\n async up() {\n await Schema.create('users', (t) => {\n t.id()\n t.string('name')\n t.string('email').unique()\n t.timestamp('email_verified_at').nullable()\n t.string('password')\n t.rememberToken()\n t.timestamps()\n })\n\n await Schema.create('password_reset_tokens', (t) => {\n t.string('email').primary()\n t.string('token')\n t.timestamp('created_at').nullable()\n })\n\n await Schema.create('sessions', (t) => {\n t.string('id').primary()\n t.foreignId('user_id').nullable().index()\n t.string('ip_address', 45).nullable()\n t.text('user_agent').nullable()\n t.longText('payload')\n t.integer('last_activity').index()\n })\n }\n\n async down() {\n await Schema.dropIfExists('users')\n await Schema.dropIfExists('password_reset_tokens')\n await Schema.dropIfExists('sessions')\n }\n}\n";
5953
- /** Sanctum's create_personal_access_tokens_table (written by install:api). */
6689
+ /** Sanctum's create_personal_access_tokens_table, as new apps ship it in database/migrations. */
5954
6690
  declare const PERSONAL_ACCESS_TOKENS_MIGRATION = "import { Migration, Schema } from '@orieljs/framework'\n\nexport default class extends Migration {\n async up() {\n await Schema.create('personal_access_tokens', (t) => {\n t.id()\n t.morphs('tokenable')\n t.string('name')\n t.string('token', 64).unique()\n t.text('abilities').nullable()\n t.timestamp('last_used_at').nullable()\n t.timestamp('expires_at').nullable()\n t.timestamps()\n })\n }\n\n async down() {\n await Schema.dropIfExists('personal_access_tokens')\n }\n}\n";
5955
6691
 
5956
6692
  /** Laravel's Illuminate\Auth\Access\Response: what an ability or policy method may return instead of a boolean. */
@@ -6831,6 +7567,13 @@ declare class RedisRepository extends Repository {
6831
7567
  private readonly redisStore;
6832
7568
  private readonly redis;
6833
7569
  constructor(redisStore: RedisStore, redis: Redis$1);
7570
+ /**
7571
+ * Closes the redis client (CacheManager.disconnectAll() at shutdown): a connected one with QUIT, one that never
7572
+ * connected or is reconnecting without waiting; one already closed is left alone. A client two stores share is quit
7573
+ * once: QUIT resolves on the server's reply, but the client reads 'ready' until its socket closes, so the second
7574
+ * store waits on the first one's QUIT instead of sending another (which would fail with "Connection is closed.").
7575
+ */
7576
+ disconnect(): Promise<void>;
6834
7577
  tags(names: string | string[]): CacheRepository;
6835
7578
  }
6836
7579
 
@@ -6846,6 +7589,12 @@ declare class CacheManager implements CacheManager$1 {
6846
7589
  private buildDatabaseStore;
6847
7590
  private buildRedisStore;
6848
7591
  store(name?: string): CacheRepository;
7592
+ /**
7593
+ * Closes the redis clients of the stores resolved so far and forgets the stores, so the next use builds them again
7594
+ * (the app's shutdown calls it). Stores without a connection to close are only forgotten. A store that fails to
7595
+ * close doesn't keep the others open: all are closed, then its error is thrown (several: an AggregateError).
7596
+ */
7597
+ disconnectAll(): Promise<void>;
6849
7598
  extend(driver: string, factory: Driver$1): void;
6850
7599
  get<T = unknown>(key: string, defaultValue?: T | (() => T)): Promise<T | undefined>;
6851
7600
  many<T = unknown>(keys: string[]): Promise<Record<string, T | undefined>>;
@@ -7037,6 +7786,8 @@ interface S3ClientLike {
7037
7786
  }
7038
7787
  interface S3DiskConfig {
7039
7788
  bucket: string;
7789
+ /** The bucket's region, for `url()`'s host. Default: us-east-1, as the client's. */
7790
+ region?: string;
7040
7791
  /** Public base URL for `url()`, e.g. a CloudFront domain. Falls back to the S3 virtual-hosted URL. */
7041
7792
  url?: string;
7042
7793
  endpoint?: string;
@@ -7071,6 +7822,12 @@ declare class S3Filesystem implements Filesystem {
7071
7822
  size(path: string): Promise<number>;
7072
7823
  lastModified(path: string): Promise<Date>;
7073
7824
  mimeType(path: string): Promise<string | undefined>;
7825
+ /**
7826
+ * The object's public URL, as the SDK builds it (Flysystem's getObjectUrl()): the key encoded, on the configured
7827
+ * `url`, else on the endpoint or the region's S3 host, with the bucket as a subdomain or, path-style, in the path.
7828
+ * Laravel leaves the key unencoded on a configured `url`; here it is encoded there too. Only the join onto a
7829
+ * configured `url` trims a leading slash, as Laravel does; elsewhere the key is kept as `put()` stores it.
7830
+ */
7074
7831
  url(path: string): string;
7075
7832
  temporaryUrl(path: string, expiresAt: Date): Promise<string>;
7076
7833
  files(directory?: string, recursive?: boolean): Promise<string[]>;
@@ -7632,6 +8389,10 @@ declare class Worker {
7632
8389
  /** F2: the promise handling the most recently leaked unhandled rejection, awaited by process() before it decides
7633
8390
  * whether the job succeeded, so failing it is never racing the "processed" event. */
7634
8391
  private pendingRejection;
8392
+ /** Laravel's $lastRestart: the restart flag when the daemon started, or UNREAD while the cache can't be read. */
8393
+ private lastRestart;
8394
+ /** Whether the last read of the restart flag failed, so an outage is reported once rather than after every job. */
8395
+ private restartFlagFailing;
7635
8396
  constructor(manager: QueueManager$1, container: Container$1, listener?: WorkerListener);
7636
8397
  /** Runs until a stop condition; returns the exit code. `queue` may be a comma-separated priority list. */
7637
8398
  daemon(connectionName: string, queue: string, options: WorkerOptions): Promise<number>;
@@ -7664,7 +8425,13 @@ declare class Worker {
7664
8425
  private calculateBackoff;
7665
8426
  private stopIfNecessary;
7666
8427
  memoryExceeded(limitMb: number): boolean;
8428
+ /**
8429
+ * Laravel's queueShouldRestart(), except that a cache that fails doesn't stop the worker: while the flag can't be
8430
+ * read the worker keeps going, and when it couldn't be read at start, the first value read becomes the baseline,
8431
+ * so a queue:restart broadcast after that still stops it.
8432
+ */
7667
8433
  private queueShouldRestart;
8434
+ /** The restart flag, or UNREAD when the cache fails (reported once per outage, never thrown). */
7668
8435
  private getTimestampOfLastQueueRestart;
7669
8436
  /** Reports through the ExceptionHandler when bound, and tells the listener. Never throws. */
7670
8437
  private report;
@@ -7801,6 +8568,12 @@ declare const QUEUE_JOB: unique symbol;
7801
8568
  declare const CHAIN: unique symbol;
7802
8569
  /** The unique-lock spec set after acquiring the lock; Queue copies it to payload.uniqueLock and releases it. */
7803
8570
  declare const UNIQUE_LOCK: unique symbol;
8571
+ /**
8572
+ * The uniqueness of the class a wrapper job runs (a queued mailable, notification or listener), set on the wrapper by
8573
+ * Mail, Notifications and Events, which can't import Bus. isUnique() and UniqueLock read it instead of the job's own
8574
+ * members; being symbol-keyed it never reaches the payload (the lock itself travels as payload.uniqueLock).
8575
+ */
8576
+ declare const UNIQUE: unique symbol;
7804
8577
  interface ChainSpec {
7805
8578
  jobs: Job[];
7806
8579
  connection?: string;
@@ -7812,16 +8585,37 @@ interface UniqueLockSpec {
7812
8585
  store?: string;
7813
8586
  untilProcessing: boolean;
7814
8587
  }
8588
+ /** What a wrapper carries under UNIQUE: the lock is `oriel_unique_job:<name>:<id>`. */
8589
+ interface UniqueSpec {
8590
+ /** The wrapped class, as the job's displayName(): `OrderShipped`, not `SendQueuedMailable`. */
8591
+ name: string;
8592
+ /** The wrapped object's uniqueId(), '' when it has none (one at a time per class, as Laravel). */
8593
+ id: string;
8594
+ /** uniqueFor in seconds; 0 or none means the lock lasts until the job is done. */
8595
+ for?: number;
8596
+ /** uniqueUntilProcessing: the lock goes when the job starts rather than when it is done. */
8597
+ untilProcessing?: boolean;
8598
+ /** uniqueVia(): the cache store holding the lock. */
8599
+ via?: string;
8600
+ }
7815
8601
  /**
7816
8602
  * Whether dispatch() queues the job: it carries ShouldQueue's `shouldQueue: true` (a `readonly shouldQueue = true`
7817
8603
  * field, or the Queueable base class's getter), the SHOULD_QUEUE symbol, a value for any ShouldQueue option, or
7818
8604
  * defines uniqueId()/retryUntil().
7819
8605
  */
7820
8606
  declare function isQueueable(job: unknown): boolean;
7821
- /** Laravel's ShouldBeUnique: the job defines uniqueId(), uniqueFor, uniqueUntilProcessing or uniqueVia(). */
8607
+ /**
8608
+ * Laravel's ShouldBeUnique: the job defines uniqueId(), uniqueFor, uniqueUntilProcessing or uniqueVia(), or carries
8609
+ * the UNIQUE spec of the class it wraps.
8610
+ */
7822
8611
  declare function isUnique(job: unknown): boolean;
8612
+ /** Seconds from a delay given as seconds or a Date (here rather than in Dispatcher.ts, so PendingBatch needs no cycle). */
8613
+ declare function delaySeconds(delay: unknown): number;
7823
8614
 
7824
- /** Laravel's UniqueLock. The lock lives in `uniqueVia()`'s cache store (a store name) or the default store. */
8615
+ /**
8616
+ * Laravel's UniqueLock. The lock lives in `uniqueVia()`'s cache store (a store name) or the default store. A wrapper
8617
+ * job (queued mail, notification or listener) is locked under the class it wraps, from its UNIQUE spec.
8618
+ */
7825
8619
  declare class UniqueLock {
7826
8620
  private readonly cache;
7827
8621
  constructor(cache: CacheManager$1);
@@ -7836,7 +8630,7 @@ declare class UniqueLock {
7836
8630
  private store;
7837
8631
  }
7838
8632
 
7839
- /** Bus.batch([...]): stores the batch, then queues every job with its batchId. */
8633
+ /** Bus.batch([...]): stores the batch, then queues every job with its batchId (and its own delay). */
7840
8634
  declare class PendingBatch implements PendingBatch$1 {
7841
8635
  private readonly container;
7842
8636
  private readonly jobs;
@@ -7865,8 +8659,6 @@ declare class PendingBatch implements PendingBatch$1 {
7865
8659
  dispatch(): Promise<Batch$1>;
7866
8660
  }
7867
8661
 
7868
- /** Seconds from a delay given as seconds or a Date. */
7869
- declare function delaySeconds(delay: unknown): number;
7870
8662
  /** Laravel's Illuminate\Bus\Dispatcher. */
7871
8663
  declare class Dispatcher implements BusDispatcher {
7872
8664
  #private;
@@ -8155,7 +8947,8 @@ declare const QueuedMailSender: Token<QueuedMailSender>;
8155
8947
  * Carries `SHOULD_QUEUE` on its own prototype, per the Queue/Bus protocol, so `BusDispatcher.dispatch()` — which
8156
8948
  * re-decides queued-or-now on whatever job it's handed — actually enqueues it instead of running it inline; the
8157
8949
  * mailable's own queueability (checked by MailerImpl) only decides whether to wrap it at all. Like Laravel's
8158
- * SendQueuedMailable, it forwards failed(), retryUntil(), middleware() and displayName() to the mailable.
8950
+ * SendQueuedMailable, it forwards failed(), retryUntil(), middleware() and displayName() to the mailable. Unlike
8951
+ * Laravel's, it is unique when the mailable is (Laravel pushes a mailable straight to the queue, past the unique lock).
8159
8952
  */
8160
8953
  declare class SendQueuedMailable implements Job {
8161
8954
  readonly mailerName: string | undefined;
@@ -8556,9 +9349,28 @@ declare class EncryptHistory implements Middleware {
8556
9349
  handle(request: HttpRequest, next: Next$1): Promise<Response>;
8557
9350
  }
8558
9351
 
9352
+ /** Laravel's $request->isPrecognitive(): this request only asks whether its data would pass (a `precognitive` route). */
9353
+ declare function isPrecognitive(request: HttpRequest): boolean;
9354
+ /**
9355
+ * Laravel's HandlePrecognitiveRequests (the `precognitive` alias): a request with `Precognition: true` (Inertia's
9356
+ * `useForm().validate()`, `<Form validate>`, laravel-precognition) runs the route's action only up to its validation.
9357
+ * Passing answers 204 with `Precognition-Success: true`; failing, the usual 422 with the errors; and nothing after the
9358
+ * validation runs. `Precognition-Validate-Only: name,email` checks those fields only. Every response varies on
9359
+ * `Precognition`, an error's too: the middleware renders what is thrown through it before adding its headers.
9360
+ *
9361
+ * Oriel validates inside the action (`await StoreUserRequest.validate()`, `request().validate({…})`), where Laravel
9362
+ * resolves the FormRequest before calling it, so a precognitive route must validate before it changes anything: what
9363
+ * comes before the validation runs. An action that answers a success without validating is an error (a 500) on any
9364
+ * method but GET and HEAD, which answer 204 as Laravel does; a redirect or an error goes through as it is.
9365
+ */
9366
+ declare class HandlePrecognitiveRequests implements Middleware {
9367
+ handle(request: HttpRequest, next: Next$1): Promise<Response>;
9368
+ }
9369
+
8559
9370
  /**
8560
9371
  * Binds the Inertia factory (one root factory, plus a scoped child per request), the SSR gateway and the
8561
- * `inertia.encrypt` middleware alias, merges config/inertia defaults and registers the inertia:* commands.
9372
+ * `inertia.encrypt` and `precognitive` middleware aliases, merges config/inertia defaults and registers the inertia:*
9373
+ * commands.
8562
9374
  */
8563
9375
  declare class InertiaServiceProvider extends ServiceProvider$1 {
8564
9376
  register(): void;
@@ -8698,4 +9510,4 @@ type SharedPropsFrom<M> = M extends {
8698
9510
  share(...args: never[]): infer R;
8699
9511
  } ? SerializedObject<Awaited<R>> : Record<never, never>;
8700
9512
 
8701
- export { API_ROUTES_STUB, AboutCommand, AbstractPaginator, AccessGate, AddQueuedCookiesToResponse, type AfterCallback, AllMailersFailedError, AlwaysProp, AnonymousNotifiable, Application, ApplicationBuilder, ArgonHasher, type ArgonOptions, type ArgumentDefinition, ArraySessionHandler, ArrayTransport, Artisan, Attempting, type Attributes$1 as Attributes, type AttributesResolver, Auth, AuthManager, type AuthModel, type AuthModelBase, type AuthModelConstructor, AuthServiceProvider, AuthenticatableModel, Authenticate, AuthenticationError, Authorizable, type AuthorizableConstructor, AuthorizationError, AuthorizationErrorImpl, Authorize, BaseJob, BaseLogger, BasePipeline, BaseRouter, BaseUrlGenerator, Batch, type BatchAttributes, BatchingUnavailableError, BcryptHasher, type BcryptOptions, type BeforeCallback, BelongsTo, BelongsToMany, BindingResolutionError, Blueprint, type BlueprintCommand, BufferedConsoleOutput, Builder, type BuiltInCast, type BuiltinRule, BuiltinRuleObject, type BunDatabase, BunSqliteDatabase, type BunStatement, Bus, Dispatcher as BusDispatcherImpl, BusError, BusServiceProvider, CACHE_TABLE_MIGRATION, CHAIN, Cache, CacheManager, CacheRateLimiter, Repository as CacheRepositoryImpl, CacheServiceProvider, type Store as CacheStore, CallQueuedHandler, CallQueuedListener, type CanResetPassword, type CanResetPasswordUser, type CastDefinition, type CastsAttributes, type ChainSpec, type CipherName, CircularDependencyError, ClosureCommand, ClosureKernel, Collection, type Column, type ColumnAttributes, ColumnDefinition, type ColumnInfo, type ColumnRef, type ColumnType, Command, CommandNotFoundError, ComponentNotFoundError, Connection, type ConsoleInput, type ConsoleIo, Kernel as ConsoleKernelImpl, type ConsoleOutput, ConsoleServiceProvider, Container, ContainerNotAvailableError, Controller, ControllerMethodNotFoundError, ConvertEmptyStringsToNull, Cookie, type CookieDefaults, CookieJar, CookieServiceProvider, CookieSessionHandler, CookieValuePrefix, type CreateMigrationOptions, Crypt, Cursor, type CursorPage, CursorPaginator, type CursorPaginatorOptions, DB, DEFAULT_MESSAGES, DailyRotatingStream, DatabaseBatchRepository, type DatabaseCommandContext, type DatabaseConfig, DatabaseConfigError, DatabaseError, DatabaseFailedJobProvider, DatabaseJob, type DatabaseJobRecord, DatabaseLock, DatabaseManagerImpl, DatabaseNotification, DatabaseNotificationChannel, DatabaseNotificationCollection, DatabaseNotificationsRelation, DatabaseQueue, type DatabaseQueueOptions, DatabaseServiceProvider, DatabaseSessionHandler, DatabaseStore, DatabaseTokenRepository, DatabaseUnavailableError, DecryptError, DeferProp, DiagnosingHealth, type Direction, Dispatchable, type EagerLoadSpec, EloquentUserProvider, EmailVerificationRequest, type Encoded, EncryptCookies, EncryptError, EncryptHistory, Encrypter, EncryptionServiceProvider, EnsureEmailIsVerified, type EnumLike, type ErrorClass, ErrorHandler, Event, Dispatcher$1 as EventDispatcherImpl, type EventKey, type EventListenMap, EventServiceProvider, EventsNeedBusDispatcherError, EventsNeedClassRegistryError, ExceptionsConfiguration, Expression, Facade, Factory, type FactoryResult, Failed, FailoverTransport, Faker, FakerOverflowError, FileNotFoundError, FileSessionHandler, FileStore, FilesystemManager, FilesystemServiceProvider, ForeignIdColumnDefinition, ForeignKeyDefinition, FormRequest, FormUploadedFile, Gate, type GateAbility, GateResponse, GeneratorCommand, GenericLock, type GlobalScope, Grammar, type GroupAttributes, type GroupHost, GroupRegistrar, type GuardFactory, HasApiTokens, HasDatabaseNotifications, type HasDatabaseNotificationsModel, type HasFactory, HasMany, HasManyThrough, HasOne, HasOneOrMany, HasUlids, HasUuids, Hash, HashAlgorithmError, type HashInfo, HashManager, type HasherFactory, type HashingConfig, HashingServiceProvider, type Having, type HealthPage, HelpCommand, type HttpCommandOptions, HttpException, Kernel$1 as HttpKernelImpl, HttpRedirectResponse, HttpRedirector, HttpResponseException, HttpResponseFactory, HttpServerError, HttpServiceProvider, Hub, IncomingRequest, type IncomingRequestOptions, type IndexType, Inertia, InertiaError, InertiaHtml, InertiaMiddleware, InertiaPage, Response$1 as InertiaPageResponse, ResponseFactory as InertiaResponseFactory, InertiaServiceProvider, type ValidationErrors as InertiaValidationErrors, type InferRuleType, type InferValidatedType, InvalidCacheConfigError, InvalidCastError, InvalidListenerError, InvalidLogLevelError, InvalidRuleParameterError, InvalidSignatureError, InvalidUrlSignatureError, JOBS_TABLE_MIGRATION, JobClassNotFoundError, type JobContext, type JobMiddleware, JobSerializationError, JoinClause, type JoinType, type JsonWhenCallback, KEY_GENERATE_SIGNATURE, type KernelApp, type KeyGenerateIO, LEVEL_SEVERITY, LazyCollection, type LengthAwarePage, LengthAwarePaginator, ListCommand, type ListenerTuple, type LocalDiskConfig, LocalFilesystem, type LockFactory, LockTimeoutError, Lockout, Log, LogChannelCycleError, LogManager, LogServiceProvider, LogTransport, type LoggedQuery, LogicError, Login, Logout, MIGRATION_CREATE_STUB, MIGRATION_STUB, MIGRATION_UPDATE_STUB, MODEL_EVENTS, Mail, MailManager, MailMessage, type MailMessageAction, MailNotificationChannel, MailQueueUnavailableError, MailServiceProvider, type MailTransporter, MailUnavailableError, Mailable, MailerImpl, MakeCastCommand, MakeCommandCommand, MakeControllerCommand, MakeEventCommand, MakeFactoryCommand, MakeJobCommand, MakeListenerCommand, MakeMailCommand, MakeMiddlewareCommand, MakeModelCommand, MakeNotificationCommand, MakeObserverCommand, MakePolicyCommand, MakeProviderCommand, MakeRequestCommand, MakeResourceCommand, MakeRuleCommand, MakeSeederCommand, MakeTestCommand, type Manifest, type ManifestChunk, ManuallyFailedError, type Many, MassAssignmentError, MaxAttemptsExceededError, MemoryStore, MergeProp, MessageBagImpl, MethodNotAllowedHttpError, MiddlewareConfiguration, MiddlewareNotFoundError, Migration, MigrationCreator, type MigrationRecord, MigrationRepository, type MigrationStatus, Migrator, type MigratorOptions, MissingAppKeyError, MissingModelError, MissingRecipientError, Model, type ModelBuilder, type ModelClass, type ModelConstructor, type ModelEvent, type ModelListener, ModelNotFoundError, ModelRegistry, type MorphConstraint, MorphMany, MorphOne, MorphTo, MySqlSchemaGrammar, NOTIFICATIONS_TABLE, NOTIFICATIONS_TABLE_MIGRATION, type NewAccessToken, NodeConsoleInput, NodeConsoleOutput, NotDatabaseNotifiableError, NotFoundHttpError, Notifiable, type NotifiableConstructor, Notification, Dispatcher$2 as NotificationDispatcherImpl, NotificationDispatcherUnavailableError, NotificationFacade, NotificationQueueUnavailableError, NotificationsServiceProvider, NullFailedJobProvider, NullLogger, NullQueue, OPERATORS, OnceProp, type OptionDefinition, OptionValue, OptionalProp, type Order, PERSONAL_ACCESS_TOKENS_MIGRATION, type PagePropsFrom, type PaginationLink, Paginator, type PaginatorOptions, type ParsedInput, type ParsedRule, type ParsedSetCookie, type ParsedSignature, Password, PasswordBroker, PasswordBrokerManager, PasswordReset, PasswordRule, PathTraversalError, PendingBatch, PendingChain, PendingDispatch, PersonalAccessToken, PinoLogger, PipelineError, PipelineServiceProvider, Pivot, type PivotIds, type PlainNotificationMail, type PolicyClass, PostgresSchemaGrammar, type PreloadAttributesResolver, PropsResolver, ProviderBootError, ProviderRegisterError, QUEUE_JOB, Builder$1 as QueryBuilder, QueryError, Queue, QueueBase, type QueueCommandContext, QueueError, type QueueJobPayload, Listener as QueueListener, type ListenerConfig as QueueListenerConfig, type ListenerOptions as QueueListenerOptions, type ListenerOutput as QueueListenerOutput, QueueManager, QueueServiceProvider, QueueUnavailableError, Queueable, QueuedConsoleInput, QueuedMailSender, type QueuedMailableFactory, RESTART_CACHE_KEY, RateLimiter, type RawResult, type RecipientOverrides, RedirectIfAuthenticated, RedisJob, RedisLock, RedisQueue, type RedisQueueOptions, RedisRepository, type RedisSessionClient, RedisSessionHandler, RedisStore, RedisTaggedStore, type ReferentialAction, Registered, type RegisteredModel, Relation, type RelationConstraint, type RelationNames, RelationNotFoundError, RelationNotLoadedError, type RelationValue, type RenderCallback, type RenderedContent, type ReplStarter, type ReportCallback, Repository$1 as Repository, ResetPassword, type ResetPasswordMail, type ResolvedMiddleware, type ResolvedServeOptions, type ResourceMethod, type ResourceRoute, type RollbackOptions, Route, type RouteAttributes, type RouteBinder, RouteDefinition, type RouteFileCallback, type RouteHandler, type RouteListFilters, type RouteListRow, RouteModelNotFoundError, RouteModelResolverImpl, RouteName, RouteNotDefinedError, type RouteStage, RoutesNotifications, RoutingError, type RoutingOptions, RoutingServiceProvider, Rule, type RuleContext, type RunningServer, type Runtime, type S3ClientLike, type S3DiskConfig, S3Filesystem, SSR_RENDER_FAILED, STORAGE_LINK_SIGNATURE, Schedule, ScheduleClearCacheCommand, ScheduleImpl, ScheduleListCommand, ScheduleNameRequiredError, ScheduleRunCommand, ScheduleWorkCommand, type ScheduleWorkOptions, ScheduledEventImpl, Schema, SchemaBuilder, SchemaBuilderToken, SchemaGrammar, type Scope, type ScopeCallback, type ScopeStatic, type Scopes, type ScrollMetadata, ScrollProp, Seeder, type SeederClass, type SelectColumn, SendEmailVerificationNotification, SendQueuedMailable, SendQueuedNotifications, type Serialized, type SerializedObject, type ServeOptions, ServiceProvider$1 as ServiceProvider, SessionFacade as Session, type SessionConfig, SessionGuard, type SessionGuardOptions, type SessionHandlerFactory, SessionManager, SessionMessageBag, SessionServiceProvider, Store$1 as SessionStore, type SharedPropsFrom, type SimplePage, type SmtpConfig, SmtpTransport, SoftDeletingScope, type SpawnResult, type SpawnWorker, type Spawner, SqliteSchemaGrammar, SsrError, type SsrFailure, HttpGateway as SsrHttpGateway, type StackFrame, StackLogger, StartSession, type State, type StateContext, Storage, type StoredBatchOptions, type StringPipeResolver, Stringable, type SyncChanges, SyncJob, SyncQueue, type TagAttributes, TagsNotSupportedError, TestCommand, ThrottleRequests, ThrottleRequestsError, TimeoutExceededError, TinkerCommand, type TinkerOptions, type TinkerRepl, TokenGuard, type TokenGuardOptions, TokenMismatchError, TokenRepository, type TransporterFactory, TrimStrings, TypeGenerator, type TypeGeneratorOptions, type TypedRedirector, UNIQUE_LOCK, USERS_TABLE_MIGRATION, UniqueJobsNeedCacheError, UniqueLock, type UniqueLockSpec, UnknownCacheDriverError, UnknownCacheStoreError, UnknownDiskError, UnknownFilesystemDriverError, UnknownLogChannelError, UnknownLogDriverError, UnknownMailTransportError, UnknownMailerError, UnknownNotificationChannelError, UnknownQueueConnectionError, UnknownQueueDriverError, UnknownValidationRuleError, UnrenderableNotificationDataError, UnrenderableNotificationMailError, UnsupportedCipherError, UnsupportedOperationError, type UriParameter, UrlGenerationError, type UrlResolver, type UserProviderFactory, ValidateSignature, Validated, ValidationErrorImpl, ValidationException, ValidationFactoryImpl, ValidationServiceProvider, Validator, ValidatorImpl, type VerifiableUser, Verified, VerifyCsrfToken, VerifyEmail, type VerifyEmailMail, ViewFactoryUnavailableError, Vite, ViteError, ViteHtml, WORKER_DISCOVERY_DIRECTORIES, type Where, type WhereArgs, type WhereBoolean, WithoutOverlapping, Worker, type WorkerListener, type WorkerOptions, abort, abortIf, abortUnless, addApiRouting, allowGuests, applyExceptionCallbacks, applyMiddlewareCallbacks, applyReplacements, auth, back, bcrypt, builtinRules, bunRuntime, cache, castGet, castSet, classNameOf, clientAddress, columnKey, compareRoutes, contentDisposition, cookie, createDailyChannel, createDialect, createPayload, createSingleChannel, createStderrChannel, createToken, csrfToken, currentContainer, currentLogContext, currentRequest, currentVite, databaseConfigDefaults, debugPage, decodePayload, decrypt, defaultAttributeName, defaultListenerOptions, defaultLockFactory, defaultProviders, defaultWorkerOptions, delaySeconds, describeError, deserialize, detectRuntime, discoverClasses, discoverFactories, discoverJobs, discoverListeners, discoverPolicies, dispatch, dispatchRoute, dispatchSync, encodePayload, encrypt, enumValues, env, errorBagFrom, errors, escapeHtml, event, exceedsJsonDepth, expandWildcardKeys, extensionFromMime, fake, filterRouteList, formatAddress, formatDate, formatDateTime, formatRouteList, formatTimestamp, fromEntries, generateAppKey, generateModelTypes, getMorphAlias, getMorphedModel, guessTable, hashInfo, healthResponse, inertia, inertiaBody, inertiaHead, inject, ipMatches, isBlank, isBun, isDateCast, isEmptyValue, isEquivalent, isJsonCast, isListenerClass, isListenerTuple, isModel, isQueueable, isQueueableListener, isUnique, isUploadedFileLike, joinDiskPath, keyGenerateHandler, listenerOptionsFrom, loadRelations, loadRoutesFrom, logger, makeFailedJobProvider, meetsLevel, mergeGroup, mergeLogContext, mergeRecursive, migrationDatePrefix, minimalPage, modelEventName, morphMap, normalizeAddress, normalizeAddresses, normalizeBackoff, normalizeLists, normalizePath, normalizeUri, old, openSqlite, optionalCookieJar, optionalSession, orderForBindings, parseArgv, parseBracketKey, parseCookieHeader, parseDateTime, parseKey, parseParameters, parseRuleSpec, parseSignature, passwordVerify, prepareValue, queueConfigDefaults, queueOptionsOf, raw as rawSql, rawWithBindings, redirect, registerHttpCommands, registerKeyGenerateCommand, registerMigrationCommands, registerModelTypesCommand, registerQueueCommands, registerStorageLinkCommand, renderContent, renderError, request, requestScope, resolveArguments, resolveDiskPath, resolveMiddleware, resolveMorphClass, resolveOptions, resourceRoutes, response, restoreJob, restoreValue, roundTrip, route, routeListRows, runConsole, runConsoleAndExit, runMiddleware, runSeeder, sanitize, sendEmailVerificationUsing, sendNotification, serialize, serializeContext, serializeCookie, serializeDate, serializeValue, serve, serveBun, serveNode, servePublicFile, session, setClientAddress, stackFrames, statusFor, statusText, storageLinkHandler, substituteBindings, suggest, summarizeValidation, toNotifiableList, toResponse, toWebRequest, tokenableType, transformLeaves, url, usePaginationResolvers, validateRequiredArguments, vite, viteReactRefresh, withHeaders, workerOptionsFrom, writeResponse };
9513
+ export { API_ROUTES_STUB, AboutCommand, AbstractPaginator, AccessGate, AddQueuedCookiesToResponse, type AfterCallback, AllMailersFailedError, AlwaysProp, AnonymousNotifiable, Application, ApplicationBuilder, ArgonHasher, type ArgonOptions, type ArgumentDefinition, ArraySessionHandler, ArrayTransport, Artisan, Attempting, type Attributes$1 as Attributes, type AttributesResolver, Auth, AuthManager, type AuthModel, type AuthModelBase, type AuthModelConstructor, AuthServiceProvider, AuthenticatableModel, Authenticate, AuthenticationError, Authorizable, type AuthorizableConstructor, AuthorizationError, AuthorizationErrorImpl, Authorize, BaseJob, BaseLogger, BasePipeline, BaseRouter, BaseUrlGenerator, Batch, type BatchAttributes, BatchingUnavailableError, BcryptHasher, type BcryptOptions, type BeforeCallback, BelongsTo, BelongsToMany, BindingResolutionError, Blueprint, type BlueprintCommand, BufferedConsoleOutput, Builder, type BuiltInCast, type BuiltinRule, BuiltinRuleObject, type BunDatabase, BunSqliteDatabase, type BunStatement, Bus, Dispatcher as BusDispatcherImpl, BusError, BusServiceProvider, CACHE_TABLE_MIGRATION, CHAIN, Cache, CacheManager, CacheRateLimiter, Repository as CacheRepositoryImpl, CacheServiceProvider, type Store as CacheStore, CallQueuedHandler, CallQueuedListener, type CanResetPassword, type CanResetPasswordUser, type CastDefinition, type CastsAttributes, type ChainSpec, type CipherName, CircularDependencyError, ClosureCommand, ClosureKernel, Collection, type Column, type ColumnAttributes, ColumnDefinition, type ColumnInfo, type ColumnRef, type ColumnType, Command, CommandNotFoundError, ComponentNotFoundError, Config, Connection, type ConsoleInput, type ConsoleIo, Kernel as ConsoleKernelImpl, type ConsoleOutput, ConsoleServiceProvider, Container, ContainerNotAvailableError, Controller, ControllerMethodNotFoundError, ConvertEmptyStringsToNull, Cookie, type CookieDefaults, CookieJar, CookieServiceProvider, CookieSessionHandler, CookieValuePrefix, type CreateMigrationOptions, Crypt, Cursor, type CursorPage, CursorPaginator, type CursorPaginatorOptions, DB, DEFAULT_MESSAGES, DailyRotatingStream, DatabaseBatchRepository, type DatabaseCommandContext, type DatabaseConfig, DatabaseConfigError, DatabaseError, DatabaseFailedJobProvider, DatabaseJob, type DatabaseJobRecord, DatabaseLock, DatabaseManagerImpl, DatabaseNotification, DatabaseNotificationChannel, DatabaseNotificationCollection, DatabaseNotificationsRelation, DatabaseQueue, type DatabaseQueueOptions, DatabaseServiceProvider, DatabaseSessionHandler, DatabaseStore, DatabaseTokenRepository, DatabaseUnavailableError, type DatePart, type DateWhereArgs, type DateWhereValue, DecryptError, DeferProp, DiagnosingHealth, type Direction, Dispatchable, type EagerLoadSpec, EloquentCollection, EloquentUserProvider, EmailVerificationRequest, type Encoded, EncryptCookies, EncryptError, EncryptHistory, Encrypter, EncryptionServiceProvider, EnsureEmailIsVerified, type EnumLike$1 as EnumLike, type ErrorClass, ErrorHandler, Event, Dispatcher$1 as EventDispatcherImpl, type EventKey, type EventListenMap, EventServiceProvider, EventsNeedBusDispatcherError, EventsNeedClassRegistryError, ExceptionsConfiguration, type ExpandingRule, Expression, Facade, Factory, type FactoryResult, Failed, FailoverTransport, Faker, FakerOverflowError, FileNotFoundError, FileSessionHandler, FileStore, FilesystemManager, FilesystemServiceProvider, ForeignIdColumnDefinition, ForeignKeyDefinition, type ForeignKeyInfo, FormRequest, FormUploadedFile, Gate, type GateAbility, GateResponse, GeneratorCommand, GenericLock, type GlobalScope, Grammar, type GroupAttributes, type GroupHost, GroupRegistrar, type GuardFactory, HandlePrecognitiveRequests, HasApiTokens, HasDatabaseNotifications, type HasDatabaseNotificationsModel, type HasFactory, HasMany, HasManyThrough, HasOne, HasOneOrMany, HasUlids, HasUuids, Hash, HashAlgorithmError, type HashInfo, HashManager, type HasherFactory, type HashingConfig, HashingServiceProvider, type Having, type HealthPage, HelpCommand, type HttpCommandOptions, HttpException, Kernel$1 as HttpKernelImpl, HttpRedirectResponse, HttpRedirector, HttpResponseException, HttpResponseFactory, HttpServerError, HttpServiceProvider, Hub, IncomingRequest, type IncomingRequestOptions, type IndexInfo, type IndexType, Inertia, InertiaError, InertiaHtml, InertiaMiddleware, InertiaPage, Response$1 as InertiaPageResponse, ResponseFactory as InertiaResponseFactory, InertiaServiceProvider, type ValidationErrors as InertiaValidationErrors, InferValidatedType, InvalidCacheConfigError, InvalidCastError, InvalidListenerError, InvalidLogLevelError, InvalidRuleParameterError, InvalidSignatureError, InvalidUrlSignatureError, JOBS_TABLE_MIGRATION, JobClassNotFoundError, type JobContext, type JobMiddleware, JobSerializationError, JoinClause, type JoinType, type JsonWhenCallback, KEY_GENERATE_SIGNATURE, type KernelApp, type KeyGenerateIO, LEVEL_SEVERITY, LazyCollection, type LengthAwarePage, LengthAwarePaginator, ListCommand, type ListenerTuple, type LocalDiskConfig, LocalFilesystem, type LockFactory, LockTimeoutError, Lockout, Log, LogChannelCycleError, LogManager, LogServiceProvider, LogTransport, type LoggedQuery, LogicError, Login, Logout, MIGRATION_CREATE_STUB, MIGRATION_STUB, MIGRATION_UPDATE_STUB, MODEL_EVENTS, Mail, type MailLevel, MailManager, MailMessage, type MailMessageAction, MailNotificationChannel, MailQueueUnavailableError, MailServiceProvider, type MailTransporter, MailUnavailableError, Mailable, MailerImpl, MakeCastCommand, MakeCommandCommand, MakeControllerCommand, MakeEventCommand, MakeFactoryCommand, MakeJobCommand, MakeListenerCommand, MakeMailCommand, MakeMiddlewareCommand, MakeModelCommand, MakeNotificationCommand, MakeObserverCommand, MakePolicyCommand, MakeProviderCommand, MakeRequestCommand, MakeResourceCommand, MakeRuleCommand, MakeSeederCommand, MakeTestCommand, type Manifest, type ManifestChunk, ManuallyFailedError, type Many, MassAssignmentError, MaxAttemptsExceededError, MemoryStore, MergeProp, MessageBagImpl, MethodNotAllowedHttpError, MiddlewareConfiguration, MiddlewareNotFoundError, Migration, MigrationCreator, type MigrationRecord, MigrationRepository, type MigrationStatus, Migrator, type MigratorOptions, MissingAppKeyError, MissingModelError, MissingRecipientError, Model, type ModelBuilder, type ModelClass, type ModelConstructor, type ModelEvent, type ModelListener, ModelNotFoundError, ModelRegistry, type MorphConstraint, MorphMany, MorphOne, MorphTo, MySqlSchemaGrammar, NOTIFICATIONS_TABLE, NOTIFICATIONS_TABLE_MIGRATION, type NewAccessToken, NodeConsoleInput, NodeConsoleOutput, NotDatabaseNotifiableError, NotFoundHttpError, Notifiable, type NotifiableConstructor, Notification, Dispatcher$2 as NotificationDispatcherImpl, NotificationDispatcherUnavailableError, NotificationFacade, NotificationQueueUnavailableError, NotificationsServiceProvider, NullFailedJobProvider, NullLogger, NullQueue, OPERATORS, OnceProp, type OptionDefinition, OptionValue, OptionalProp, type Order, PERSONAL_ACCESS_TOKENS_MIGRATION, type PagePropsFrom, type PaginationLink, Paginator, type PaginatorOptions, type ParsedInput, type ParsedRule, type ParsedSetCookie, type ParsedSignature, Password, PasswordBroker, PasswordBrokerManager, PasswordReset, PasswordRule, PathTraversalError, PendingBatch, PendingChain, PendingDispatch, PersonalAccessToken, PinoLogger, PipelineError, PipelineServiceProvider, Pivot, type PivotIds, type PlainNotificationMail, type PolicyClass, PostgresSchemaGrammar, type PreloadAttributesResolver, PropsResolver, ProviderBootError, ProviderRegisterError, QUEUE_JOB, Builder$1 as QueryBuilder, QueryError, Queue, QueueBase, type QueueCommandContext, QueueError, type QueueJobPayload, Listener as QueueListener, type ListenerConfig as QueueListenerConfig, type ListenerOptions as QueueListenerOptions, type ListenerOutput as QueueListenerOutput, QueueManager, QueueServiceProvider, QueueUnavailableError, Queueable, QueuedConsoleInput, QueuedMailSender, type QueuedMailableFactory, RESTART_CACHE_KEY, RateLimiter, type RawResult, type RecipientOverrides, RedirectIfAuthenticated, RedisJob, RedisLock, RedisQueue, type RedisQueueOptions, RedisRepository, type RedisSessionClient, RedisSessionHandler, RedisStore, RedisTaggedStore, type ReferentialAction, Registered, type RegisteredModel, Relation, type RelationConstraint, type RelationNames, RelationNotFoundError, RelationNotLoadedError, type RelationValue, type RenderCallback, type RenderedContent, type ReplStarter, type ReportCallback, Repository$1 as Repository, ResetPassword, type ResetPasswordMail, type ResolvedMiddleware, type ResolvedServeOptions, type ResourceMethod, type ResourceRoute, type RollbackOptions, Route, RouteArguments, type RouteAttributes, type RouteBinder, RouteDefinition, type RouteFileCallback, type RouteHandler, type RouteListFilters, type RouteListRow, RouteModelNotFoundError, RouteModelResolverImpl, RouteName, RouteNotDefinedError, type RouteStage, RoutesNotifications, RoutingError, type RoutingOptions, RoutingServiceProvider, Rule, type RuleContext, type RunningServer, type Runtime, type S3ClientLike, type S3DiskConfig, S3Filesystem, SCHEDULE_INTERRUPT_KEY, SSR_RENDER_FAILED, STORAGE_LINK_SIGNATURE, Schedule, ScheduleClearCacheCommand, type ScheduleClock, ScheduleImpl, ScheduleInterruptCommand, ScheduleListCommand, ScheduleNameRequiredError, ScheduleRunCommand, ScheduleWorkCommand, type ScheduleWorkOptions, ScheduledEventImpl, Schema, SchemaBuilder, SchemaBuilderToken, SchemaGrammar, type SchemaStep, type Scope, type ScopeCallback, type ScopeStatic, type Scopes, type ScrollMetadata, ScrollProp, Seeder, type SeederClass, type SelectColumn, SendEmailVerificationNotification, SendQueuedMailable, SendQueuedNotifications, type Serialized, type SerializedObject, type ServeOptions, ServiceProvider$1 as ServiceProvider, SessionFacade as Session, type SessionConfig, SessionGuard, type SessionGuardOptions, type SessionHandlerFactory, SessionManager, SessionMessageBag, SessionServiceProvider, Store$1 as SessionStore, type SharedPropsFrom, type SimplePage, type SmtpConfig, SmtpTransport, SoftDeletingScope, type SpawnResult, type SpawnWorker, type Spawner, SqliteSchemaGrammar, SsrError, type SsrFailure, HttpGateway as SsrHttpGateway, type StackFrame, StackLogger, StartSession, type State, type StateContext, Storage, type StoredBatchOptions, type StringPipeResolver, Stringable, type SyncChanges, SyncJob, SyncQueue, type TableRebuild, type TagAttributes, TagsNotSupportedError, TestCommand, ThrottleRequests, ThrottleRequestsError, TimeoutExceededError, TinkerCommand, type TinkerOptions, type TinkerRepl, TokenGuard, type TokenGuardOptions, TokenMismatchError, TokenRepository, type TransporterFactory, TrimStrings, TypeGenerator, type TypeGeneratorOptions, type TypedRedirector, UNIQUE, UNIQUE_LOCK, USERS_TABLE_MIGRATION, UniqueJobsNeedCacheError, UniqueLock, type UniqueLockSpec, type UniqueSpec, UnknownCacheDriverError, UnknownCacheStoreError, UnknownDiskError, UnknownFilesystemDriverError, UnknownLogChannelError, UnknownLogDriverError, UnknownMailTransportError, UnknownMailerError, UnknownNotificationChannelError, UnknownQueueConnectionError, UnknownQueueDriverError, UnknownValidationRuleError, UnrenderableNotificationDataError, UnrenderableNotificationMailError, UnsupportedCipherError, UnsupportedOperationError, type UriParameter, UrlGenerationError, type UrlResolver, type UserProviderFactory, ValidateSignature, Validated, ValidationErrorImpl, ValidationException, ValidationFactoryImpl, ValidationServiceProvider, Validator, ValidatorImpl, type VerifiableUser, Verified, VerifyCsrfToken, VerifyEmail, type VerifyEmailMail, ViewFactoryUnavailableError, Vite, ViteError, ViteHtml, WORKER_DISCOVERY_DIRECTORIES, type Where, type WhereArgs, type WhereBoolean, WithoutOverlapping, Worker, type WorkerListener, type WorkerOptions, abort, abortIf, abortUnless, addApiRouting, allowGuests, applyExceptionCallbacks, applyMiddlewareCallbacks, applyReplacements, auth, back, bcrypt, builtinRules, bunRuntime, cache, castGet, castSet, classNameOf, clientAddress, columnKey, compareRoutes, contentDisposition, cookie, createDailyChannel, createDialect, createPayload, createSingleChannel, createStderrChannel, createToken, csrfToken, currentContainer, currentLogContext, currentRequest, currentVite, databaseConfigDefaults, debugPage, decodePayload, decrypt, defaultAttributeName, defaultListenerOptions, defaultLockFactory, defaultProviders, defaultWorkerOptions, delaySeconds, describeError, deserialize, detectRuntime, discoverClasses, discoverFactories, discoverJobs, discoverListeners, discoverPolicies, dispatch, dispatchRoute, dispatchSync, encodePayload, encrypt, enumValues, env, errorBagFrom, errors, escapeHtml, event, exceedsJsonDepth, expandWildcardKeys, extensionFromMime, fake, filterRouteList, formatAddress, formatDate, formatDateTime, formatRouteList, formatTimestamp, fromEntries, generateAppKey, generateModelTypes, getMorphAlias, getMorphedModel, guessTable, hashInfo, healthResponse, inertia, inertiaBody, inertiaHead, inject, ipMatches, isBlank, isBun, isDateCast, isEmptyValue, isEquivalent, isJsonCast, isListenerClass, isListenerTuple, isModel, isPrecognitive, isQueueable, isQueueableListener, isTableRebuild, isUnique, isUploadedFileLike, joinDiskPath, keyGenerateHandler, listenerOptionsFrom, loadRelations, loadRoutesFrom, logger, makeFailedJobProvider, meetsLevel, mergeGroup, mergeLogContext, mergeRecursive, migrationDatePrefix, minimalPage, modelEventName, morphMap, normalizeAddress, normalizeAddresses, normalizeBackoff, normalizeLists, normalizePath, normalizeUri, old, openSqlite, optionalCookieJar, optionalSession, orderForBindings, parseArgv, parseBracketKey, parseCookieHeader, parseDateTime, parseKey, parseParameters, parseRuleSpec, parseSignature, passwordVerify, prepareValue, queueConfigDefaults, queueOptionsOf, raw as rawSql, rawWithBindings, redirect, registerHttpCommands, registerKeyGenerateCommand, registerMigrationCommands, registerModelTypesCommand, registerQueueCommands, registerStorageLinkCommand, renderContent, renderError, request, requestScope, resolveArguments, resolveDiskPath, resolveMiddleware, resolveMorphClass, resolveOptions, resourceRoutes, response, restoreJob, restoreValue, roundTrip, route, routeListRows, runConsole, runConsoleAndExit, runMiddleware, runSeeder, sanitize, sendEmailVerificationUsing, sendNotification, serialize, serializeContext, serializeCookie, serializeDate, serializeValue, serve, serveBun, serveNode, servePublicFile, session, setClientAddress, stackFrames, statusFor, statusText, storageLinkHandler, substituteBindings, suggest, summarizeValidation, toNotifiableList, toResponse, toWebRequest, tokenableType, transformLeaves, url, usePaginationResolvers, validateRequiredArguments, vite, viteReactRefresh, withHeaders, workerOptionsFrom, writeResponse };