@orieljs/framework 0.1.0-alpha.1 → 0.1.0-alpha.10

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 (87) hide show
  1. package/NOTICE +7 -0
  2. package/README.md +10 -1
  3. package/TRADEMARKS.md +33 -0
  4. package/dist/chunk-7ZQZYDOC.js +3253 -0
  5. package/dist/chunk-7ZQZYDOC.js.map +1 -0
  6. package/dist/{chunk-K6MAA3RM.js → chunk-GVNLZZTN.js} +7 -1
  7. package/dist/chunk-GVNLZZTN.js.map +1 -0
  8. package/dist/chunk-OXAATQA6.js +8433 -0
  9. package/dist/chunk-OXAATQA6.js.map +1 -0
  10. package/dist/{chunk-WI7E7Q46.js → chunk-VOYW3R5J.js} +8 -4
  11. package/dist/chunk-VOYW3R5J.js.map +1 -0
  12. package/dist/contracts.d.ts +841 -168
  13. package/dist/contracts.js +7 -1
  14. package/dist/index.d-WQpfdIbG.d.ts +630 -0
  15. package/dist/index.d.ts +2916 -5178
  16. package/dist/index.js +7357 -2609
  17. package/dist/index.js.map +1 -1
  18. package/dist/{jsx-runtime-B8J6xq-7.d.ts → jsx-runtime-6um4Mwfb.d.ts} +99 -149
  19. package/dist/jsx-runtime.d.ts +3 -1
  20. package/dist/jsx-runtime.js +3 -3
  21. package/dist/testing-CKwfWJGn.d.ts +1586 -0
  22. package/dist/testing.d.ts +3 -1408
  23. package/dist/testing.js +29 -5
  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 +652 -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 +35 -30
  82. package/dist/chunk-AI2RFMBT.js +0 -745
  83. package/dist/chunk-AI2RFMBT.js.map +0 -1
  84. package/dist/chunk-BZPCRKFQ.js +0 -2941
  85. package/dist/chunk-BZPCRKFQ.js.map +0 -1
  86. package/dist/chunk-K6MAA3RM.js.map +0 -1
  87. package/dist/chunk-WI7E7Q46.js.map +0 -1
@@ -35,148 +35,32 @@ interface Container {
35
35
  }
36
36
  declare const Container: Token<Container>;
37
37
 
38
- interface ServiceProvider {
39
- /** Bind things into the container. Synchronous. Don't resolve other services here. */
40
- register?(): void;
41
- /** Runs after every provider is registered. May be async (e.g. importing route files). */
42
- boot?(): void | Promise<void>;
43
- }
44
- type ServiceProviderClass = new (app: Application) => ServiceProvider;
45
- interface Application extends Container {
46
- readonly version: string;
47
- basePath(path?: string): string;
48
- appPath(path?: string): string;
49
- bootstrapPath(path?: string): string;
50
- configPath(path?: string): string;
51
- databasePath(path?: string): string;
52
- publicPath(path?: string): string;
53
- resourcePath(path?: string): string;
54
- storagePath(path?: string): string;
55
- /** With no args returns the environment name. With args returns whether it matches any of them. */
56
- environment(): string;
57
- environment(...environments: string[]): boolean;
58
- isProduction(): boolean;
59
- isLocal(): boolean;
60
- runningInConsole(): boolean;
61
- /** Mark the app as running in the console (the CLI entry point calls this). Defaults to true. */
62
- setRunningInConsole(value?: boolean): void;
63
- runningUnitTests(): boolean;
64
- /** Registers the provider. If the app is already booted, the provider is booted immediately. */
65
- register(provider: ServiceProvider | ServiceProviderClass): Promise<ServiceProvider>;
66
- getProviders(): ServiceProvider[];
67
- boot(): Promise<void>;
68
- isBooted(): boolean;
69
- booting(callback: (app: Application) => void | Promise<void>): void;
70
- booted(callback: (app: Application) => void | Promise<void>): void;
71
- /** Handle one HTTP request in a fresh request scope via the bound HttpKernel. */
72
- handle(request: Request): Promise<Response>;
73
- /** Register a callback that terminate() runs, in registration order. */
74
- terminating(callback: () => void | Promise<void>): void;
75
- terminate(): Promise<void>;
76
- }
77
- declare const Application: Token<Application>;
78
- interface ExceptionHandler {
79
- report(error: unknown): Promise<void>;
80
- shouldReport(error: unknown): boolean;
81
- /** `request` is the scoped HttpRequest (Contracts/Http) when available, else the raw Request. */
82
- render(request: unknown, error: unknown): Promise<Response>;
83
- }
84
- declare const ExceptionHandler: Token<ExceptionHandler>;
85
- /** Paths passed to Application.configure().withRouting(). Routing (Wave 1) loads them. */
86
- interface RoutingPaths {
87
- web?: string;
88
- api?: string;
89
- console?: string;
90
- health?: string;
91
- apiPrefix: string;
92
- }
93
- declare const RoutingPaths: Token<RoutingPaths>;
94
- /** The object passed to Application.configure().withExceptions(e => …), like Laravel's Exceptions class. */
95
- interface ExceptionsConfigurator {
96
- /** Custom reporting. Return false to stop the default logging. */
97
- report(callback: (error: unknown) => void | boolean | Promise<void | boolean>): this;
98
- /** Custom rendering. Return undefined to fall through to the default rendering. */
99
- render(callback: (error: unknown, request: unknown) => Response | undefined | Promise<Response | undefined>): this;
100
- /** Never report errors of these classes. */
101
- dontReport(...classes: Array<abstract new (...args: never[]) => Error>): this;
102
- }
103
- /** Callbacks collected by withMiddleware()/withExceptions(); invoked by Http / the exception handler (Wave 1). */
104
- type ConfigCallbacks<T> = Array<(configurator: T) => void>;
105
- /** Typed as unknown here because MiddlewareConfigurator lives in Contracts/Http; Http casts on use. */
106
- declare const MiddlewareCallbacks: Token<ConfigCallbacks<unknown>>;
107
- declare const ExceptionCallbacks: Token<ConfigCallbacks<ExceptionsConfigurator>>;
108
-
109
- interface ConfigRepository {
110
- has(key: string): boolean;
111
- /** Dot notation: get('database.connections.sqlite.database'). */
112
- get<T = unknown>(key: string, defaultValue?: T): T;
113
- set(key: string, value: unknown): void;
114
- set(values: Record<string, unknown>): void;
115
- push(key: string, value: unknown): void;
116
- all(): Record<string, unknown>;
117
- }
118
- declare const ConfigRepository: Token<ConfigRepository>;
119
-
120
- interface Arrayable<T = unknown> {
121
- toArray(): T;
122
- }
123
- interface Jsonable {
124
- toJson(): string;
125
- }
126
- interface Htmlable {
127
- toHtml(): string;
128
- }
129
- /** Anything a controller can return that knows how to become a Response. */
130
- interface Responsable {
131
- toResponse(request: unknown): Response | Promise<Response>;
132
- }
133
- /** The minimal collection surface contracts rely on (implemented by @orieljs/collections). */
134
- interface Enumerable<T> extends Iterable<T>, Arrayable<unknown[]> {
135
- all(): T[];
136
- count(): number;
137
- isEmpty(): boolean;
138
- }
139
- interface ClassRegistry {
140
- /** Registers under `name` (default: cls.name). Throws if the name is already taken by a different class. */
141
- register(cls: Class<unknown>, name?: string): string;
142
- nameOf(cls: Class<unknown>): string | undefined;
143
- resolve<T = unknown>(name: string): Class<T>;
144
- has(name: string): boolean;
145
- }
146
- declare const ClassRegistry: Token<ClassRegistry>;
147
-
148
- type PipeNext<T> = (passable: T) => Promise<unknown>;
149
- type PipeClosure<T> = (passable: T, next: PipeNext<T>) => Promise<unknown> | unknown;
150
- /** A class resolved from the container whose `via` method (default 'handle') is called; or a string alias 'name:param1,param2'. */
151
- type Pipe<T> = PipeClosure<T> | Class<object> | string;
152
- interface Pipeline<T = unknown> {
153
- send(passable: T): this;
154
- through(pipes: ReadonlyArray<Pipe<T>>): this;
155
- pipe(...pipes: Array<Pipe<T>>): this;
156
- /** Method called on class pipes. Default 'handle'. */
157
- via(method: string): this;
158
- then<R>(destination: (passable: T) => R | Promise<R>): Promise<R>;
159
- thenReturn(): Promise<T>;
160
- }
161
- interface PipelineFactory {
162
- make<T>(): Pipeline<T>;
163
- }
164
- declare const PipelineFactory: Token<PipelineFactory>;
165
-
166
38
  /** The session of the current request (scoped). Loaded and saved by the StartSession middleware. */
167
39
  interface Session {
168
40
  getId(): string;
169
41
  start(): Promise<void>;
170
42
  save(): Promise<void>;
171
43
  all(): Record<string, unknown>;
44
+ only(keys: string[]): Record<string, unknown>;
45
+ except(keys: string[]): Record<string, unknown>;
46
+ /** Whether every key is present, even with a null value. */
47
+ exists(...keys: string[]): boolean;
48
+ missing(...keys: string[]): boolean;
49
+ /** Whether the key is present and not null. */
172
50
  has(key: string): boolean;
173
51
  get<T = unknown>(key: string, defaultValue?: T): T;
174
52
  put(key: string | Record<string, unknown>, value?: unknown): void;
175
53
  push(key: string, value: unknown): void;
54
+ /** Adds `amount` (default 1) to the number under the key and returns the new value. */
55
+ increment(key: string, amount?: number): number;
56
+ decrement(key: string, amount?: number): number;
176
57
  pull<T = unknown>(key: string, defaultValue?: T): T;
58
+ /** Forgets the key and returns its value. */
59
+ remove<T = unknown>(key: string): T;
177
60
  forget(...keys: string[]): void;
178
61
  flush(): void;
179
- flash(key: string, value: unknown): void;
62
+ /** Puts the value (true when omitted) for the next request only. */
63
+ flash(key: string, value?: unknown): void;
180
64
  now(key: string, value: unknown): void;
181
65
  reflash(): void;
182
66
  keep(...keys: string[]): void;
@@ -198,6 +82,370 @@ interface SessionHandler {
198
82
  gc(maxLifetimeSeconds: number): Promise<void>;
199
83
  }
200
84
 
85
+ /**
86
+ * What one rule tells the validated data's type about a value that passed it. Every member is optional:
87
+ * - `value`: the type of a passing value. A field's type is the intersection of its rules' values
88
+ * (`'string|in:a,b'` is `'a' | 'b'`); a field whose rules set none is `unknown`.
89
+ * - `presence`: `'required'` puts the key in the data and rules out null (`required`, `accepted`); `'present'` puts
90
+ * the key in the data; `'filled'` rules out null without putting the key in; `'excluded'` leaves the key out;
91
+ * `'optional'` may leave the key out whatever else would put it in (`sometimes` skips a missing key, and a rule that
92
+ * excludes the field under a condition drops it with its children), so the key is optional and doesn't put its
93
+ * parent in. A key nothing puts in is optional, as the validated data has only the keys the input had.
94
+ * - `each`: on a field that also has `array`, the type of each item instead of `value` (`in` checks every item of an
95
+ * array: `'array|in:a,b'` is `Array<'a' | 'b'>`).
96
+ * - `nullable`: null passes, unless a `'required'` or `'filled'` rule says otherwise.
97
+ */
98
+ interface RuleTyping {
99
+ value?: unknown;
100
+ each?: unknown;
101
+ presence?: 'required' | 'present' | 'filled' | 'excluded' | 'optional';
102
+ nullable?: true;
103
+ }
104
+ /** A number, or the text of one: a form sends every field as text, and `integer` and `numeric` accept both. */
105
+ type NumericValue = number | `${number}`;
106
+ /** `a,b,c` → `'a' | 'b' | 'c'`: a rule's comma-separated parameters, as Validator splits them. */
107
+ type RuleParameterList<P extends string> = P extends `${infer Head},${infer Tail}` ? Head | RuleParameterList<Tail> : P;
108
+ /**
109
+ * What `in` (and `Rule.in()`) lets through: it compares the value's text with each listed value, so `'1'` lets the
110
+ * number 1 through too, and `'true'` the boolean. A list known only as `string` (`` `in:${list.join(',')}` ``) says
111
+ * nothing, as any value whose text is listed passes.
112
+ */
113
+ type InValue<V> = string extends V ? unknown : V extends string ? V | (V extends `${infer N extends number}` ? N : never) | (V extends 'true' ? true : V extends 'false' ? false : never) : V extends number | boolean ? V | `${V}` : V;
114
+ /**
115
+ * The string rules that tell the validated data's type something, by name, each a RuleTyping. `Parameters` is the
116
+ * rule's text after the colon (`'a,b'` for `in:a,b`). A rule that only checks a value it doesn't change the type of
117
+ * (`max`, `confirmed`, `unique`) has no entry. Add a member for a new type-setting rule; an app adds its own
118
+ * `Validator.extend()` rules by declaration merging, with the same type parameter.
119
+ */
120
+ interface ValidationRuleTypes<Parameters extends string = string> {
121
+ required: {
122
+ presence: 'required';
123
+ };
124
+ /** Skips the field when the key is missing, so the key may be left out even with `required`. */
125
+ sometimes: {
126
+ presence: 'optional';
127
+ };
128
+ nullable: {
129
+ nullable: true;
130
+ };
131
+ accepted: {
132
+ presence: 'required';
133
+ value: true | 1 | 'yes' | 'on' | '1' | 'true';
134
+ };
135
+ declined: {
136
+ presence: 'required';
137
+ value: false | 0 | 'no' | 'off' | '0' | 'false';
138
+ };
139
+ present: {
140
+ presence: 'present';
141
+ };
142
+ filled: {
143
+ presence: 'filled';
144
+ };
145
+ missing: {
146
+ presence: 'excluded';
147
+ };
148
+ exclude: {
149
+ presence: 'excluded';
150
+ };
151
+ /** Drop the field, children and all, under a condition, so the key may be left out even with `required`. */
152
+ exclude_if: {
153
+ presence: 'optional';
154
+ };
155
+ exclude_unless: {
156
+ presence: 'optional';
157
+ };
158
+ exclude_with: {
159
+ presence: 'optional';
160
+ };
161
+ exclude_without: {
162
+ presence: 'optional';
163
+ };
164
+ /**
165
+ * Passes only when the field is missing or empty, so a value that is there is null, blank or whitespace-only text,
166
+ * [] or {}.
167
+ */
168
+ prohibited: {
169
+ value: null | string | [] | Record<string, never>;
170
+ };
171
+ string: {
172
+ value: string;
173
+ };
174
+ /** `integer:strict` and `numeric:strict` refuse the text of a number. */
175
+ integer: {
176
+ value: Parameters extends 'strict' ? number : NumericValue;
177
+ };
178
+ numeric: {
179
+ value: Parameters extends 'strict' ? number : NumericValue;
180
+ };
181
+ /** `boolean:strict` lets only true and false through. */
182
+ boolean: {
183
+ value: Parameters extends 'strict' ? boolean : boolean | 0 | 1 | '0' | '1';
184
+ };
185
+ /** `array` is a list; `array:a,b` an object whose keys are among those named. */
186
+ array: {
187
+ value: Parameters extends '' ? unknown[] : {
188
+ [K in RuleParameterList<Parameters>]?: unknown;
189
+ };
190
+ };
191
+ list: {
192
+ value: unknown[];
193
+ };
194
+ contains: {
195
+ value: unknown[];
196
+ };
197
+ doesnt_contain: {
198
+ value: unknown[];
199
+ };
200
+ required_array_keys: {
201
+ value: {
202
+ [K in RuleParameterList<Parameters>]: unknown;
203
+ };
204
+ };
205
+ in_array_keys: {
206
+ value: Record<string, unknown>;
207
+ };
208
+ email: {
209
+ value: string;
210
+ };
211
+ url: {
212
+ value: string;
213
+ };
214
+ uuid: {
215
+ value: string;
216
+ };
217
+ alpha: {
218
+ value: string;
219
+ };
220
+ alpha_num: {
221
+ value: string;
222
+ };
223
+ alpha_dash: {
224
+ value: string;
225
+ };
226
+ regex: {
227
+ value: string;
228
+ };
229
+ lowercase: {
230
+ value: string | number;
231
+ };
232
+ uppercase: {
233
+ value: string | number;
234
+ };
235
+ ascii: {
236
+ value: string | number;
237
+ };
238
+ hex_color: {
239
+ value: string;
240
+ };
241
+ json: {
242
+ value: string;
243
+ };
244
+ ip: {
245
+ value: string;
246
+ };
247
+ ipv4: {
248
+ value: string;
249
+ };
250
+ ipv6: {
251
+ value: string;
252
+ };
253
+ mac_address: {
254
+ value: string;
255
+ };
256
+ ulid: {
257
+ value: string;
258
+ };
259
+ timezone: {
260
+ value: string;
261
+ };
262
+ active_url: {
263
+ value: string;
264
+ };
265
+ digits: {
266
+ value: NumericValue;
267
+ };
268
+ digits_between: {
269
+ value: NumericValue;
270
+ };
271
+ max_digits: {
272
+ value: NumericValue;
273
+ };
274
+ min_digits: {
275
+ value: NumericValue;
276
+ };
277
+ decimal: {
278
+ value: NumericValue;
279
+ };
280
+ multiple_of: {
281
+ value: NumericValue;
282
+ };
283
+ date: {
284
+ value: string;
285
+ };
286
+ /** A number passes a format made of digits (`Y`, `U`), as in Laravel. */
287
+ date_format: {
288
+ value: string | number;
289
+ };
290
+ /** A number passes the comparisons as a timestamp, as in Laravel; with `date` in the set, the value is text. */
291
+ before: {
292
+ value: string | number;
293
+ };
294
+ before_or_equal: {
295
+ value: string | number;
296
+ };
297
+ after: {
298
+ value: string | number;
299
+ };
300
+ after_or_equal: {
301
+ value: string | number;
302
+ };
303
+ date_equals: {
304
+ value: string | number;
305
+ };
306
+ current_password: {
307
+ value: string;
308
+ };
309
+ in: {
310
+ value: InValue<RuleParameterList<Parameters>>;
311
+ each: InValue<RuleParameterList<Parameters>>;
312
+ };
313
+ file: {
314
+ value: UploadedFile;
315
+ };
316
+ image: {
317
+ value: UploadedFile;
318
+ };
319
+ mimes: {
320
+ value: UploadedFile;
321
+ };
322
+ mimetypes: {
323
+ value: UploadedFile;
324
+ };
325
+ extensions: {
326
+ value: UploadedFile;
327
+ };
328
+ dimensions: {
329
+ value: UploadedFile;
330
+ };
331
+ }
332
+ /**
333
+ * A rule object that tells the validated data's type what it lets through, as a string rule's entry in
334
+ * ValidationRuleTypes does. `__typing` is never set or read at run time: declare it (`declare readonly __typing?:
335
+ * { value: string }`). A rule object without it changes nothing, so its field takes the type of the string rules
336
+ * beside it (`['required', 'string', new Uppercase()]` is a string).
337
+ */
338
+ interface TypedValidationRule<T extends RuleTyping = RuleTyping> extends ValidationRule {
339
+ readonly __typing?: T;
340
+ }
341
+ type RuleName<R extends string> = R extends `${infer Name}:${string}` ? Name : R;
342
+ type RuleParameters<R extends string> = R extends `${string}:${infer Parameters}` ? Parameters : '';
343
+ type PipeRules<S extends string> = S extends `${infer Head}|${infer Tail}` ? Head | PipeRules<Tail> : S;
344
+ /** What a rule without an entry, or a rule object without `__typing`, says: nothing. */
345
+ type NoTyping = Record<never, never>;
346
+ type StringRuleTyping<R extends string> = R extends unknown ? RuleName<R> extends keyof ValidationRuleTypes ? ValidationRuleTypes<RuleParameters<R>>[RuleName<R>] : NoTyping : never;
347
+ type ObjectRuleTyping<O> = '__typing' extends keyof O ? Exclude<O['__typing' & keyof O], undefined> : NoTyping;
348
+ type ItemTyping<I> = I extends string ? StringRuleTyping<I> : ObjectRuleTyping<I>;
349
+ /** The typings of one field's rules, as a union: `'required|string'` or `['required', 'string', rule]`. */
350
+ type SpecTypings<Spec> = Spec extends string ? StringRuleTyping<PipeRules<Spec>> : Spec extends ReadonlyArray<infer Item> ? ItemTyping<Item> : NoTyping;
351
+ /** A rule string the compiler only knows as `string` (rules written without `as const`) says nothing. */
352
+ type IsWide<Spec> = Spec extends string ? (string extends Spec ? true : false) : Spec extends ReadonlyArray<infer Item> ? (string extends Extract<Item, string> ? true : false) : false;
353
+ type Intersect<U> = (U extends unknown ? (value: U) => void : never) extends (value: infer I) => void ? I : never;
354
+ type Boxed<T> = T extends {
355
+ value: infer V;
356
+ } ? {
357
+ v: V;
358
+ } : never;
359
+ type BoxedEach<T> = T extends {
360
+ each: infer E;
361
+ } ? {
362
+ v: E;
363
+ } : never;
364
+ type Unbox<B> = [B] extends [never] ? unknown : Intersect<B> extends {
365
+ v: infer V;
366
+ } ? V : never;
367
+ type WithoutEach<T> = T extends {
368
+ each: unknown;
369
+ } ? never : T;
370
+ /** The intersection of the rules' values; on an array, the rules with `each` type its items instead. */
371
+ type ValueOf<T> = [BoxedEach<T>] extends [never] ? Unbox<Boxed<T>> : Unbox<Boxed<WithoutEach<T>>> extends readonly unknown[] ? Array<Unbox<BoxedEach<T>>> : Unbox<Boxed<T>>;
372
+ type PresenceOf<T> = T extends {
373
+ presence: infer P;
374
+ } ? P : never;
375
+ type NullableOf<T> = T extends {
376
+ nullable: true;
377
+ } ? true : never;
378
+ interface FieldInfo {
379
+ value: unknown;
380
+ required: boolean;
381
+ optional: boolean;
382
+ nullable: boolean;
383
+ excluded: boolean;
384
+ }
385
+ type FieldFrom<T, Optional = [Extract<PresenceOf<T>, 'optional'>] extends [never] ? false : true> = {
386
+ value: ValueOf<T>;
387
+ required: Optional extends true ? false : [Extract<PresenceOf<T>, 'required' | 'present'>] extends [never] ? false : true;
388
+ optional: Optional;
389
+ nullable: [NullableOf<T>] extends [never] ? false : [Extract<PresenceOf<T>, 'required' | 'filled'>] extends [never] ? true : false;
390
+ excluded: [Extract<PresenceOf<T>, 'excluded'>] extends [never] ? false : true;
391
+ };
392
+ /** Rules the compiler only knows as `string` say nothing, not even that the key is there. */
393
+ type FieldOf<Spec> = IsWide<Spec> extends true ? NoRules : FieldFrom<SpecTypings<Spec>>;
394
+ type NoRules = {
395
+ value: unknown;
396
+ required: false;
397
+ optional: false;
398
+ nullable: false;
399
+ excluded: false;
400
+ };
401
+ type Keys<R> = Extract<keyof R, string>;
402
+ type Head<K extends string> = K extends `${infer H}.${string}` ? H : K;
403
+ type Heads<R> = Head<Keys<R>>;
404
+ type Children<R, H extends string> = {
405
+ [K in Keys<R> as K extends `${H}.${infer Rest}` ? Rest : never]: R[K];
406
+ };
407
+ type HasChildren<R, H extends string> = [Keys<Children<R, H>>] extends [never] ? false : true;
408
+ type Own<R, H extends string> = H extends keyof R ? FieldOf<R[H]> : NoRules;
409
+ type OrNull<T, Nullable> = Nullable extends true ? T | null : T;
410
+ /**
411
+ * A wildcard's rules (`items.*.name`) make an array of what they describe; dotted keys (`author.name`) an object.
412
+ * Without a rule that makes the parent a list (`array`, `list`), validated() may give an object instead: an object
413
+ * sent under `items.*` stays one, and a sparse match (`{ items: [{}, { qty: 1 }] }`) keeps its index keys.
414
+ */
415
+ type Structure<C, Parent> = '*' extends Heads<C> ? Items<ValueAt<C, '*'>, Parent> : Shape<C>;
416
+ type Items<V, Parent> = [Parent] extends [readonly unknown[]] ? V[] : V[] | Record<string, V>;
417
+ type ValueAt<R, H extends string, F extends FieldInfo = Own<R, H>> = OrNull<HasChildren<R, H> extends true ? Structure<Children<R, H>, F['value']> : F['value'], F['nullable']>;
418
+ /**
419
+ * A key is in the data when a rule puts it there, or when a child key without a wildcard is required, unless a rule
420
+ * may leave it out.
421
+ */
422
+ type IsRequired<R, H extends string> = Own<R, H>['optional'] extends true ? false : Own<R, H>['required'] extends true ? true : HasChildren<R, H> extends true ? '*' extends Heads<Children<R, H>> ? false : [RequiredHeads<Children<R, H>>] extends [never] ? false : true : false;
423
+ type RequiredHeads<R> = {
424
+ [H in Heads<R>]: Own<R, H>['excluded'] extends true ? never : IsRequired<R, H> extends true ? H : never;
425
+ }[Heads<R>];
426
+ type Simplify<T> = {
427
+ [K in keyof T]: T[K];
428
+ } & {};
429
+ type Shape<R> = string extends Keys<R> ? Record<string, unknown> : Simplify<{
430
+ [H in Heads<R> as Own<R, H>['excluded'] extends true ? never : IsRequired<R, H> extends true ? H : never]: ValueAt<R, H>;
431
+ } & {
432
+ [H in Heads<R> as Own<R, H>['excluded'] extends true ? never : IsRequired<R, H> extends true ? never : H]?: ValueAt<R, H>;
433
+ }>;
434
+ /**
435
+ * The type of one field's passing value, from its rule string: `'nullable|integer'` → `number | \`${number}\` | null`.
436
+ * A rule string the compiler only knows as `string` gives unknown.
437
+ */
438
+ type InferRuleType<S extends string> = string extends S ? unknown : OrNull<FieldOf<S>['value'], FieldOf<S>['nullable']>;
439
+ /**
440
+ * The validated data a Rules object gives: nested as Validator's validated() nests it (`author.name` → `{ author: {
441
+ * name } }`, `tags.*` → an array, or an object too unless `tags` has `array` or `list`), each key optional unless a
442
+ * rule puts it in, each value typed by its rules. Rules known only as `Rules` (or any `Record<string, …>`) give
443
+ * `Record<string, unknown>`, and rule strings known only as `string` give optional keys of unknown. Write a
444
+ * FormRequest's `rules()` with `as const` so its rule strings keep their text; `request().validate({ … })` needs
445
+ * nothing.
446
+ */
447
+ type InferValidatedType<R> = R extends unknown ? Shape<R> : never;
448
+
201
449
  /** A rule object (Laravel's ValidationRule). Call fail() to reject the value. */
202
450
  interface ValidationRule {
203
451
  validate(attribute: string, value: unknown, fail: (message: string) => void, data: Record<string, unknown>): void | Promise<void>;
@@ -205,6 +453,7 @@ interface ValidationRule {
205
453
  /** 'required|string|max:255', or an array mixing strings and rule objects. Keys support dot + `*` wildcards. */
206
454
  type Rules = Record<string, string | ReadonlyArray<string | ValidationRule>>;
207
455
  interface MessageBag {
456
+ add(key: string, message: string): void;
208
457
  has(key: string): boolean;
209
458
  first(key?: string): string | undefined;
210
459
  get(key: string): string[];
@@ -213,18 +462,21 @@ interface MessageBag {
213
462
  count(): number;
214
463
  toObject(): Record<string, string[]>;
215
464
  }
216
- interface Validator {
465
+ /** `R` is the rules' type: `validated()` is typed from them, as `request().validate()` is. */
466
+ interface Validator<R extends Rules = Rules> {
217
467
  passes(): Promise<boolean>;
218
468
  fails(): Promise<boolean>;
219
469
  /** Only the keys that have rules. Throws ValidationError (Exceptions.ts) on failure. */
220
- validated<T = Record<string, unknown>>(): Promise<T>;
470
+ validated<T = InferValidatedType<R>>(): Promise<T>;
221
471
  /** Valid only after passes()/fails()/validated() has run. */
222
472
  errors(): MessageBag;
223
473
  after(callback: (validator: Validator) => void | Promise<void>): this;
474
+ /** Adds a failure message for `field` (from an after() hook). */
475
+ fail(field: string, message: string): void;
224
476
  }
225
477
  type RuleCallback = (attribute: string, value: unknown, parameters: string[], data: Record<string, unknown>) => boolean | Promise<boolean>;
226
478
  interface ValidationFactory {
227
- make(data: Record<string, unknown>, rules: Rules, messages?: Record<string, string>, attributes?: Record<string, string>): Validator;
479
+ make<const R extends Rules>(data: Record<string, unknown>, rules: R, messages?: Record<string, string>, attributes?: Record<string, string>): Validator<R>;
228
480
  /** Registers a string rule, e.g. extend('uppercase', fn, ':attribute must be uppercase'). */
229
481
  extend(name: string, callback: RuleCallback, message?: string): void;
230
482
  }
@@ -238,7 +490,13 @@ interface UploadedFile {
238
490
  readonly mimeType: string;
239
491
  readonly size: number;
240
492
  extension(): string;
493
+ /** The extension of the name the browser gave the file, lower-cased ('' without one). */
494
+ clientExtension(): string;
495
+ /** A random 40-character name with extension(): the name store() gives the file. */
496
+ hashName(): string;
241
497
  arrayBuffer(): Promise<ArrayBuffer>;
498
+ text(): Promise<string>;
499
+ stream(): ReadableStream<Uint8Array>;
242
500
  /** Stores on a Filesystem disk. Returns the stored path. */
243
501
  store(directory: string, disk?: string): Promise<string>;
244
502
  storeAs(directory: string, name: string, disk?: string): Promise<string>;
@@ -261,6 +519,8 @@ interface HttpRequest {
261
519
  header(name: string, defaultValue: string): string;
262
520
  bearerToken(): string | undefined;
263
521
  ip(): string | undefined;
522
+ /** The raw body as text (Laravel's getContent()); '' when there is none. */
523
+ content(): string;
264
524
  expectsJson(): boolean;
265
525
  ajax(): boolean;
266
526
  query<T = unknown>(key?: string, defaultValue?: T): T;
@@ -280,11 +540,18 @@ interface HttpRequest {
280
540
  /** Route parameter (after model binding), or every parameter when called with no key. */
281
541
  route<T = unknown>(key?: string): T;
282
542
  session(): Session;
283
- /** The user resolved earlier by auth middleware. Undefined for guests. Use `await Auth.user()` to resolve lazily. */
284
- user<T = unknown>(guard?: string): T | undefined;
543
+ /**
544
+ * The signed-in user, found through the request's guard (the default one, or the one named) the first time it is
545
+ * asked for, then the same instance for the rest of the request. Undefined for a guest.
546
+ */
547
+ user<T = unknown>(guard?: string): Promise<T | undefined>;
548
+ /** How user() finds the user (Auth sets it). The resolver may return a promise. */
285
549
  setUserResolver(resolver: (guard?: string) => unknown): void;
286
- /** Validates this request's input via the ValidationFactory; throws a Validation OrielError (422) on failure. */
287
- validate<T = Record<string, unknown>>(rules: Rules, messages?: Record<string, string>, attributes?: Record<string, string>): Promise<T>;
550
+ /**
551
+ * Validates this request's input via the ValidationFactory; throws a Validation OrielError (422) on failure. The
552
+ * validated data is typed from the rules: `validate({ title: 'required|string' })` is `{ title: string }`.
553
+ */
554
+ validate<const R extends Rules>(rules: R, messages?: Record<string, string>, attributes?: Record<string, string>): Promise<InferValidatedType<R>>;
288
555
  }
289
556
  declare const HttpRequest: Token<HttpRequest>;
290
557
  type Next = (request: HttpRequest) => Promise<Response>;
@@ -313,6 +580,8 @@ interface MiddlewareConfigurator {
313
580
  except: string[];
314
581
  }): this;
315
582
  redirectGuestsTo(url: string | ((request: HttpRequest) => string)): this;
583
+ /** Where the `guest` middleware sends a signed-in user. */
584
+ redirectUsersTo(url: string | ((request: HttpRequest) => string)): this;
316
585
  }
317
586
  interface HttpKernel {
318
587
  handle(request: Request): Promise<Response>;
@@ -323,25 +592,171 @@ interface ResponseFactory {
323
592
  make(content?: BodyInit | null, status?: number, headers?: HeadersInit): Response;
324
593
  json(data: unknown, status?: number, headers?: HeadersInit): Response;
325
594
  noContent(status?: number): Response;
595
+ /** Renders the view into an HTML response. */
596
+ view(name: string, data?: Record<string, unknown>, status?: number, headers?: HeadersInit): Promise<Response>;
326
597
  download(path: string, name?: string, headers?: HeadersInit): Promise<Response>;
598
+ /** Sends the file inline, for the browser to show (download() sends it as an attachment). */
599
+ file(path: string, headers?: HeadersInit): Promise<Response>;
327
600
  stream(body: ReadableStream, status?: number, headers?: HeadersInit): Response;
328
601
  }
329
602
  declare const ResponseFactory: Token<ResponseFactory>;
330
603
 
604
+ interface ServiceProvider {
605
+ /** Bind things into the container. Synchronous. Don't resolve other services here. */
606
+ register?(): void;
607
+ /** Runs after every provider is registered. May be async (e.g. importing route files). */
608
+ boot?(): void | Promise<void>;
609
+ }
610
+ type ServiceProviderClass = new (app: Application) => ServiceProvider;
611
+ interface Application extends Container {
612
+ readonly version: string;
613
+ basePath(path?: string): string;
614
+ appPath(path?: string): string;
615
+ bootstrapPath(path?: string): string;
616
+ configPath(path?: string): string;
617
+ databasePath(path?: string): string;
618
+ publicPath(path?: string): string;
619
+ resourcePath(path?: string): string;
620
+ storagePath(path?: string): string;
621
+ /** With no args returns the environment name. With args returns whether it matches any of them. */
622
+ environment(): string;
623
+ environment(...environments: string[]): boolean;
624
+ isProduction(): boolean;
625
+ isLocal(): boolean;
626
+ runningInConsole(): boolean;
627
+ /** Mark the app as running in the console (the CLI entry point calls this). Defaults to true. */
628
+ setRunningInConsole(value?: boolean): void;
629
+ runningUnitTests(): boolean;
630
+ /** Registers the provider. If the app is already booted, the provider is booted immediately. */
631
+ register(provider: ServiceProvider | ServiceProviderClass): Promise<ServiceProvider>;
632
+ getProviders(): ServiceProvider[];
633
+ boot(): Promise<void>;
634
+ isBooted(): boolean;
635
+ booting(callback: (app: Application) => void | Promise<void>): void;
636
+ booted(callback: (app: Application) => void | Promise<void>): void;
637
+ /** Handle one HTTP request in a fresh request scope via the bound HttpKernel. */
638
+ handle(request: Request): Promise<Response>;
639
+ /** Register a callback that terminate() runs, in registration order. */
640
+ terminating(callback: () => void | Promise<void>): void;
641
+ terminate(): Promise<void>;
642
+ /**
643
+ * Register a callback that shutdown() runs once, before the process exits: close pools and clients, write out
644
+ * files. terminating() callbacks run after every request; these run once, at the end.
645
+ */
646
+ onShutdown(callback: () => void | Promise<void>): void;
647
+ /** Runs the shutdown callbacks once, newest first; a failing one is printed and the rest still run. Never rejects. */
648
+ shutdown(): Promise<void>;
649
+ }
650
+ declare const Application: Token<Application>;
651
+ interface ExceptionHandler {
652
+ report(error: unknown): Promise<void>;
653
+ shouldReport(error: unknown): boolean;
654
+ /** `request` is the scoped HttpRequest (Contracts/Http) when available, else the raw Request. */
655
+ render(request: unknown, error: unknown): Promise<Response>;
656
+ }
657
+ declare const ExceptionHandler: Token<ExceptionHandler>;
658
+ /** Paths passed to Application.configure().withRouting(). Routing (Wave 1) loads them. */
659
+ interface RoutingPaths {
660
+ /** One route file or several, loaded in order (Laravel's `withRouting(web: [...])`). */
661
+ web?: string | string[];
662
+ api?: string | string[];
663
+ console?: string;
664
+ health?: string;
665
+ apiPrefix: string;
666
+ }
667
+ declare const RoutingPaths: Token<RoutingPaths>;
668
+ /** The object passed to Application.configure().withExceptions(e => …), like Laravel's Exceptions class. */
669
+ interface ExceptionsConfigurator {
670
+ /** Custom reporting. Return false to stop the default logging. */
671
+ report(callback: (error: unknown) => void | boolean | Promise<void | boolean>): this;
672
+ /** Custom rendering. Return undefined to fall through to the default rendering. */
673
+ render(callback: (error: unknown, request: unknown) => Response | undefined | Promise<Response | undefined>): this;
674
+ /** Never report errors of these classes. */
675
+ dontReport(...classes: Array<abstract new (...args: never[]) => Error>): this;
676
+ /** Render errors as JSON when the callback returns true, whatever the Accept header. */
677
+ shouldRenderJsonWhen(callback: (request: HttpRequest, error: unknown) => boolean): this;
678
+ }
679
+ /** Callbacks collected by withMiddleware()/withExceptions(); invoked by Http / the exception handler (Wave 1). */
680
+ type ConfigCallbacks<T> = Array<(configurator: T) => void>;
681
+ /** Typed as unknown here because MiddlewareConfigurator lives in Contracts/Http; Http casts on use. */
682
+ declare const MiddlewareCallbacks: Token<ConfigCallbacks<unknown>>;
683
+ declare const ExceptionCallbacks: Token<ConfigCallbacks<ExceptionsConfigurator>>;
684
+
685
+ interface ConfigRepository {
686
+ has(key: string): boolean;
687
+ /** Dot notation: get('database.connections.sqlite.database'). */
688
+ get<T = unknown>(key: string, defaultValue?: T): T;
689
+ set(key: string, value: unknown): void;
690
+ set(values: Record<string, unknown>): void;
691
+ push(key: string, value: unknown): void;
692
+ all(): Record<string, unknown>;
693
+ }
694
+ declare const ConfigRepository: Token<ConfigRepository>;
695
+
696
+ interface Arrayable<T = unknown> {
697
+ toArray(): T;
698
+ }
699
+ interface Jsonable {
700
+ toJson(): string;
701
+ }
702
+ interface Htmlable {
703
+ toHtml(): string;
704
+ }
705
+ /** Anything a controller can return that knows how to become a Response. */
706
+ interface Responsable {
707
+ toResponse(request: unknown): Response | Promise<Response>;
708
+ }
709
+ /** The minimal collection surface contracts rely on (implemented by @orieljs/collections). */
710
+ interface Enumerable<T> extends Iterable<T>, Arrayable<unknown[]> {
711
+ all(): T[];
712
+ count(): number;
713
+ isEmpty(): boolean;
714
+ }
715
+ interface ClassRegistry {
716
+ /** Registers under `name` (default: cls.name). Throws if the name is already taken by a different class. */
717
+ register(cls: Class<unknown>, name?: string): string;
718
+ nameOf(cls: Class<unknown>): string | undefined;
719
+ resolve<T = unknown>(name: string): Class<T>;
720
+ has(name: string): boolean;
721
+ }
722
+ declare const ClassRegistry: Token<ClassRegistry>;
723
+
724
+ type PipeNext<T> = (passable: T) => Promise<unknown>;
725
+ type PipeClosure<T> = (passable: T, next: PipeNext<T>) => Promise<unknown> | unknown;
726
+ /** A class resolved from the container whose `via` method (default 'handle') is called; or a string alias 'name:param1,param2'. */
727
+ type Pipe<T> = PipeClosure<T> | Class<object> | string;
728
+ interface Pipeline<T = unknown> {
729
+ send(passable: T): this;
730
+ through(pipes: ReadonlyArray<Pipe<T>>): this;
731
+ pipe(...pipes: Array<Pipe<T>>): this;
732
+ /** Method called on class pipes. Default 'handle'. */
733
+ via(method: string): this;
734
+ then<R>(destination: (passable: T) => R | Promise<R>): Promise<R>;
735
+ thenReturn(): Promise<T>;
736
+ }
737
+ interface PipelineFactory {
738
+ make<T>(): Pipeline<T>;
739
+ }
740
+ declare const PipelineFactory: Token<PipelineFactory>;
741
+
331
742
  /** Public method names of a controller (excludes non-function members). */
332
743
  type ActionMethods<C> = {
333
744
  [K in keyof C]: C[K] extends (...args: any[]) => unknown ? K : never;
334
745
  }[keyof C] & string;
335
746
  type ControllerAction<C> = readonly [Class<C>, ActionMethods<C>];
336
747
  type RouteClosure = (...args: any[]) => unknown;
337
- type RouteAction = RouteClosure | ControllerAction<any>;
748
+ /** A class with __invoke(): Route.get('/counter', Counter) (single-action controllers, full-page Live components). */
749
+ type InvokableClass = Class<{
750
+ __invoke(...args: any[]): unknown;
751
+ }>;
752
+ type RouteAction = RouteClosure | ControllerAction<any> | InvokableClass;
338
753
  type MiddlewareReference = string | MiddlewareClass;
339
754
  interface Route {
340
755
  readonly methods: readonly string[];
341
756
  readonly uri: string;
342
757
  getName(): string | undefined;
343
758
  name(name: string): this;
344
- middleware(...middleware: MiddlewareReference[]): this;
759
+ middleware(...middleware: Array<MiddlewareReference | readonly MiddlewareReference[]>): this;
345
760
  withoutMiddleware(...middleware: MiddlewareReference[]): this;
346
761
  where(parameter: string, pattern: string): this;
347
762
  where(patterns: Record<string, string>): this;
@@ -349,7 +764,7 @@ interface Route {
349
764
  interface RouteRegistrar {
350
765
  prefix(prefix: string): RouteRegistrar;
351
766
  name(prefix: string): RouteRegistrar;
352
- middleware(...middleware: MiddlewareReference[]): RouteRegistrar;
767
+ middleware(...middleware: Array<MiddlewareReference | readonly MiddlewareReference[]>): RouteRegistrar;
353
768
  controller(controller: Class<unknown>): RouteRegistrar;
354
769
  group(routes: () => void | Promise<void>): Promise<void>;
355
770
  }
@@ -369,22 +784,24 @@ interface CurrentRoute {
369
784
  }
370
785
  declare const CurrentRoute: Token<CurrentRoute>;
371
786
  interface Router {
372
- get<C>(uri: string, action: ControllerAction<C> | RouteClosure | string): Route;
373
- post<C>(uri: string, action: ControllerAction<C> | RouteClosure | string): Route;
374
- put<C>(uri: string, action: ControllerAction<C> | RouteClosure | string): Route;
375
- patch<C>(uri: string, action: ControllerAction<C> | RouteClosure | string): Route;
376
- delete<C>(uri: string, action: ControllerAction<C> | RouteClosure | string): Route;
377
- options<C>(uri: string, action: ControllerAction<C> | RouteClosure | string): Route;
378
- any<C>(uri: string, action: ControllerAction<C> | RouteClosure | string): Route;
379
- match<C>(methods: string[], uri: string, action: ControllerAction<C> | RouteClosure | string): Route;
787
+ get<C>(uri: string, action: ControllerAction<C> | RouteClosure | InvokableClass | string): Route;
788
+ post<C>(uri: string, action: ControllerAction<C> | RouteClosure | InvokableClass | string): Route;
789
+ put<C>(uri: string, action: ControllerAction<C> | RouteClosure | InvokableClass | string): Route;
790
+ patch<C>(uri: string, action: ControllerAction<C> | RouteClosure | InvokableClass | string): Route;
791
+ delete<C>(uri: string, action: ControllerAction<C> | RouteClosure | InvokableClass | string): Route;
792
+ options<C>(uri: string, action: ControllerAction<C> | RouteClosure | InvokableClass | string): Route;
793
+ any<C>(uri: string, action: ControllerAction<C> | RouteClosure | InvokableClass | string): Route;
794
+ match<C>(methods: string[], uri: string, action: ControllerAction<C> | RouteClosure | InvokableClass | string): Route;
380
795
  redirect(from: string, to: string, status?: number): Route;
381
796
  view(uri: string, view: string, data?: Record<string, unknown>): Route;
797
+ /** Route.inertia('/about', 'About', props): a GET route that renders an Inertia page (Laravel's Route::inertia). */
798
+ inertia(uri: string, component: string, props?: Record<string, unknown>): Route;
382
799
  resource(name: string, controller: Class<unknown>, options?: ResourceOptions): void;
383
800
  apiResource(name: string, controller: Class<unknown>, options?: ResourceOptions): void;
384
801
  fallback(action: RouteAction): Route;
385
802
  prefix(prefix: string): RouteRegistrar;
386
803
  name(prefix: string): RouteRegistrar;
387
- middleware(...middleware: MiddlewareReference[]): RouteRegistrar;
804
+ middleware(...middleware: Array<MiddlewareReference | readonly MiddlewareReference[]>): RouteRegistrar;
388
805
  controller(controller: Class<unknown>): RouteRegistrar;
389
806
  /** Explicit model binding: Route.model('author', User). */
390
807
  model(parameter: string, model: Class<unknown>): void;
@@ -414,6 +831,36 @@ interface RouteModelResolver {
414
831
  resolveExplicit(model: Class<unknown>, value: string, field?: string): Promise<unknown>;
415
832
  }
416
833
  declare const RouteModelResolver: Token<RouteModelResolver>;
834
+ /**
835
+ * Route name → parameters, for the typed route() and redirect().route() helpers. Empty until `oriel route:types`
836
+ * augments it (types/routes.d.ts); while it is empty any string is accepted. The contracts themselves keep taking
837
+ * strings: the framework builds route names at run time.
838
+ */
839
+ interface RouteList {
840
+ }
841
+ /** A route name: the generated ones, or any string before `oriel route:types` has run. */
842
+ type RouteName = [keyof RouteList] extends [never] ? string : Extract<keyof RouteList, string>;
843
+ /** A route parameter's value: a scalar, or a model (its route key, or the `{post:slug}` column, goes in the URL). */
844
+ type RouteParameter = string | number | bigint | boolean | {
845
+ getRouteKey(): unknown;
846
+ };
847
+ type GeneratedParameters<N extends keyof RouteList> = {
848
+ [K in keyof RouteList[N]]: RouteParameter;
849
+ };
850
+ type RequiredParameters<P> = {
851
+ [K in keyof P]-?: Record<never, never> extends Pick<P, K> ? never : K;
852
+ }[keyof P];
853
+ /**
854
+ * A named route's parameters: named (`{ post }`, extra keys become the query string), one value (it fills the first
855
+ * parameter), or values in URI order (`[post, comment]`).
856
+ */
857
+ type RouteParameters<N extends string> = N extends keyof RouteList ? (GeneratedParameters<N> & Record<string, unknown>) | RouteParameter | readonly RouteParameter[] : unknown;
858
+ /**
859
+ * The arguments after a route name in route() and redirect().route(): the parameters, required when the route has a
860
+ * required one, then `Rest` (route()'s `absolute`, redirect().route()'s `status`). Before `oriel route:types` has
861
+ * named the route, anything is accepted.
862
+ */
863
+ type RouteArguments<N extends string, Rest extends unknown[] = [absolute?: boolean]> = N extends keyof RouteList ? [RequiredParameters<RouteList[N]>] extends [never] ? [parameters?: RouteParameters<N>, ...rest: Rest] : [parameters: RouteParameters<N>, ...rest: Rest] : [parameters?: unknown, ...rest: Rest];
417
864
  interface UrlGenerator {
418
865
  to(path: string, query?: Record<string, unknown>, absolute?: boolean): string;
419
866
  route(name: string, parameters?: unknown, absolute?: boolean): string;
@@ -421,21 +868,34 @@ interface UrlGenerator {
421
868
  current(): string;
422
869
  previous(fallback?: string): string;
423
870
  hasRoute(name: string): boolean;
871
+ /** A URL to a named route with a `signature` query (HMAC-SHA256 keyed by APP_KEY); `expiration` adds `expires`. */
872
+ signedRoute(name: string, parameters?: unknown, expiration?: Date | number, absolute?: boolean): string;
873
+ /** signedRoute() that expires: a Date, or seconds from now. */
874
+ temporarySignedRoute(name: string, expiration: Date | number, parameters?: unknown, absolute?: boolean): string;
875
+ /** Whether the request URL carries a valid, unexpired signature (`absolute: false` signs the path only). */
876
+ hasValidSignature(request: HttpRequest, absolute?: boolean): boolean;
424
877
  }
425
878
  declare const UrlGenerator: Token<UrlGenerator>;
426
879
  interface RedirectResponse extends Responsable {
427
880
  readonly targetUrl: string;
428
881
  with(key: string | Record<string, unknown>, value?: unknown): this;
429
- withErrors(errors: Record<string, string | string[]>, bag?: string): this;
882
+ /** Flashes the errors (a record, or a validator's `errors()`) into the bag, `default` unless named. */
883
+ withErrors(errors: Record<string, string | string[]> | MessageBag, bag?: string): this;
430
884
  withInput(input?: Record<string, unknown>): this;
431
885
  withCookie(name: string, value: string, minutes?: number): this;
886
+ header(name: string, value: string): this;
432
887
  }
433
888
  interface Redirector {
434
889
  to(path: string, status?: number): RedirectResponse;
435
890
  route(name: string, parameters?: unknown, status?: number): RedirectResponse;
436
891
  back(fallback?: string, status?: number): RedirectResponse;
437
- intended(fallback?: string): RedirectResponse;
892
+ intended(fallback?: string, status?: number): RedirectResponse;
438
893
  away(url: string, status?: number): RedirectResponse;
894
+ /** Remembers the URL a guest was going to (for intended()), then redirects to `path`. */
895
+ guest(path: string, status?: number): RedirectResponse;
896
+ /** Redirects to the current URL. */
897
+ refresh(status?: number): RedirectResponse;
898
+ setIntendedUrl(url: string): void;
439
899
  }
440
900
  declare const Redirector: Token<Redirector>;
441
901
 
@@ -492,6 +952,8 @@ interface ViewFactory {
492
952
  exists(name: string): boolean;
493
953
  share(key: string | Record<string, unknown>, value?: unknown): void;
494
954
  composer(views: string | string[], composer: (view: View) => void | Promise<void>): void;
955
+ /** Renders TSX (an element, a string, an Htmlable, a View, promises of them) to HTML, like Blade::render(). */
956
+ renderToString(node: unknown): Promise<string>;
495
957
  }
496
958
  declare const ViewFactory: Token<ViewFactory>;
497
959
 
@@ -512,6 +974,8 @@ interface Logger {
512
974
  interface LogManager extends Logger {
513
975
  channel(name?: string): Logger;
514
976
  stack(channels: string[]): Logger;
977
+ /** Writes out and closes the channels opened so far (log files are written asynchronously); a script awaits it last. */
978
+ flush(): Promise<void>;
515
979
  }
516
980
  declare const LogManager: Token<LogManager>;
517
981
 
@@ -602,6 +1066,8 @@ interface DatabaseConnection {
602
1066
  interface DatabaseManager extends DatabaseConnection {
603
1067
  connection(name?: string): DatabaseConnection;
604
1068
  disconnect(name?: string): Promise<void>;
1069
+ /** Closes every open connection and forgets them (the application's shutdown, the end of a test). */
1070
+ disconnectAll(): Promise<void>;
605
1071
  }
606
1072
  declare const DatabaseManager: Token<DatabaseManager>;
607
1073
  /** What non-Database components may rely on from a model instance. */
@@ -612,6 +1078,8 @@ interface ModelInstance {
612
1078
  getTable(): string;
613
1079
  getRouteKey(): unknown;
614
1080
  getRouteKeyName(): string;
1081
+ /** The value stored in a polymorphic `*_type` column for this model: its morph map alias, else its class name. */
1082
+ getMorphClass(): string;
615
1083
  getAttribute<T = unknown>(key: string): T;
616
1084
  setAttribute(key: string, value: unknown): this;
617
1085
  fill(attributes: Row): this;
@@ -627,6 +1095,19 @@ interface ModelStatic<M extends ModelInstance = ModelInstance> {
627
1095
  find(id: unknown): Promise<M | undefined>;
628
1096
  findOrFail(id: unknown): Promise<M>;
629
1097
  }
1098
+ /**
1099
+ * What decides a paginator's page and the path of its links when the request doesn't (Laravel's
1100
+ * Paginator::currentPageResolver and currentPathResolver, which Livewire's WithPagination replaces). Live binds one for
1101
+ * the application, which answers while a WithPagination component mounts, runs an update's hooks and actions, or
1102
+ * renders. Unbound, or `undefined` from a method, the paginators read the request (`?page=` and its URL).
1103
+ */
1104
+ interface PaginationState {
1105
+ /** The page to show for `pageName` ('page' by default). */
1106
+ currentPage(pageName: string): number | undefined;
1107
+ /** The base path of the page links. */
1108
+ currentPath(): string | undefined;
1109
+ }
1110
+ declare const PaginationState: Token<PaginationState>;
630
1111
 
631
1112
  interface Authenticatable {
632
1113
  getAuthIdentifierName(): string;
@@ -695,6 +1176,11 @@ interface MustVerifyEmail {
695
1176
 
696
1177
  /** Options a job class may declare as public fields. Their presence (or implementing ShouldQueue) makes things queueable. */
697
1178
  interface ShouldQueue {
1179
+ /**
1180
+ * Marks the class as queued at run time: `implements ShouldQueue` leaves no trace once compiled, so the interface
1181
+ * asks for `readonly shouldQueue = true`. Jobs, listeners, mailables and notifications carrying it are queued.
1182
+ */
1183
+ readonly shouldQueue: true;
698
1184
  connection?: string;
699
1185
  queue?: string;
700
1186
  /** Seconds. */
@@ -704,7 +1190,11 @@ interface ShouldQueue {
704
1190
  backoff?: number | number[];
705
1191
  /** Seconds. */
706
1192
  timeout?: number;
707
- uniqueId?(): string;
1193
+ /**
1194
+ * Laravel's ShouldBeUnique: while a job with this id is pending, another one is dropped. A queued listener's
1195
+ * receives the event (Laravel 13); a number is used as its string.
1196
+ */
1197
+ uniqueId?(...args: never[]): string | number;
708
1198
  }
709
1199
  /** A job: public fields are its serialized data; handle() runs on the worker (inject() works inside it). */
710
1200
  interface Job extends Partial<ShouldQueue> {
@@ -879,27 +1369,83 @@ interface ConsoleKernel {
879
1369
  command(signature: string, handler: (this: CommandContext, ...args: unknown[]) => number | void | Promise<number | void>): ClosureCommand;
880
1370
  }
881
1371
  declare const ConsoleKernel: Token<ConsoleKernel>;
1372
+ /** A callback a scheduled event runs before or after itself (before(), after(), onSuccess(), onFailure()). */
1373
+ type ScheduleHook = () => unknown;
882
1374
  interface ScheduledEvent {
883
1375
  readonly expression: string;
1376
+ /**
1377
+ * What a Schedule.command() event runs: the command and its parameters ('posts:announce --force'), without the
1378
+ * runtime and `oriel` in front. Undefined for call() and job() events. Laravel's `$event->command`.
1379
+ */
1380
+ readonly command: string | undefined;
1381
+ /** Whether withoutOverlapping() was called. Laravel's `$event->withoutOverlapping`, a method's name here. */
1382
+ readonly preventsOverlapping: boolean;
1383
+ /** Minutes the withoutOverlapping() lock is kept at most (1440 unless withoutOverlapping() says). Laravel's `$event->expiresAt`. */
1384
+ readonly expiresAt: number;
884
1385
  cron(expression: string): this;
1386
+ /**
1387
+ * Runs every N seconds: the event is due every minute, and schedule:run (or schedule:work) keeps running it until
1388
+ * the minute ends. N divides 60.
1389
+ */
1390
+ everySecond(): this;
1391
+ everyTwoSeconds(): this;
1392
+ everyFiveSeconds(): this;
1393
+ everyTenSeconds(): this;
1394
+ everyFifteenSeconds(): this;
1395
+ everyTwentySeconds(): this;
1396
+ everyThirtySeconds(): this;
885
1397
  everyMinute(): this;
1398
+ everyTwoMinutes(): this;
1399
+ everyThreeMinutes(): this;
1400
+ everyFourMinutes(): this;
886
1401
  everyFiveMinutes(): this;
1402
+ everyTenMinutes(): this;
887
1403
  everyFifteenMinutes(): this;
888
1404
  everyThirtyMinutes(): this;
889
1405
  hourly(): this;
890
- hourlyAt(minute: number): this;
1406
+ /** At these minutes past every hour. */
1407
+ hourlyAt(minute: number | readonly number[]): this;
1408
+ /** Every odd hour (1, 3, … 23), at `minute` past (0 by default). */
1409
+ everyOddHour(minute?: number | readonly number[]): this;
1410
+ everyTwoHours(minute?: number | readonly number[]): this;
1411
+ everyThreeHours(minute?: number | readonly number[]): this;
1412
+ everyFourHours(minute?: number | readonly number[]): this;
1413
+ everySixHours(minute?: number | readonly number[]): this;
891
1414
  daily(): this;
1415
+ /** The same as dailyAt(). */
1416
+ at(time: string): this;
892
1417
  dailyAt(time: string): this;
893
1418
  twiceDaily(first?: number, second?: number): this;
1419
+ /** At hours `first` and `second`, `minute` past. */
1420
+ twiceDailyAt(first?: number, second?: number, minute?: number): this;
1421
+ weekdays(): this;
1422
+ weekends(): this;
1423
+ mondays(): this;
1424
+ tuesdays(): this;
1425
+ wednesdays(): this;
1426
+ thursdays(): this;
1427
+ fridays(): this;
1428
+ saturdays(): this;
1429
+ sundays(): this;
894
1430
  weekly(): this;
895
- weeklyOn(day: number, time?: string): this;
1431
+ /** On these days of the week (0 = Sunday … 6 = Saturday), at `time` ('0:0' by default). */
1432
+ weeklyOn(day: number | readonly number[], time?: string): this;
896
1433
  monthly(): this;
897
- monthlyOn(day: number, time?: string): this;
1434
+ monthlyOn(day?: number, time?: string): this;
1435
+ twiceMonthly(first?: number, second?: number, time?: string): this;
1436
+ /** On the last day of every month, at `time`. */
1437
+ lastDayOfMonth(time?: string): this;
1438
+ quarterly(): this;
1439
+ /** On day `day` of the first month of each quarter, at `time`. */
1440
+ quarterlyOn(day?: number, time?: string): this;
898
1441
  yearly(): this;
899
- weekdays(): this;
900
- weekends(): this;
1442
+ yearlyOn(month?: number, day?: number, time?: string): this;
1443
+ /** On these days of the week (0 = Sunday … 6 = Saturday): `days([1, 3])` or `days(1, 3)`. */
1444
+ days(days: number | readonly number[], ...more: number[]): this;
901
1445
  timezone(timezone: string): this;
902
1446
  between(start: string, end: string): this;
1447
+ /** Skips the event between these times (a window may cross midnight: '23:00', '4:00'). */
1448
+ unlessBetween(start: string, end: string): this;
903
1449
  when(callback: () => boolean | Promise<boolean>): this;
904
1450
  skip(callback: () => boolean | Promise<boolean>): this;
905
1451
  /** Uses a cache lock (default 1440 minutes). */
@@ -909,6 +1455,22 @@ interface ScheduledEvent {
909
1455
  runInBackground(): this;
910
1456
  name(name: string): this;
911
1457
  description(description: string): this;
1458
+ /** Runs before the event, once its filters and locks let it run. */
1459
+ before(callback: ScheduleHook): this;
1460
+ /** Runs after the event, whether it succeeded or failed (also then()). */
1461
+ after(callback: ScheduleHook): this;
1462
+ then(callback: ScheduleHook): this;
1463
+ /** Runs after the event when it succeeded: a command exited 0, a closure neither threw nor returned false. */
1464
+ onSuccess(callback: ScheduleHook): this;
1465
+ /** Runs after the event when it failed: a command exited non-zero, a closure threw or returned false. */
1466
+ onFailure(callback: ScheduleHook): this;
1467
+ /** The name, else the description: the command, the job's class, or 'Closure'. schedule:list shows it. */
1468
+ getSummaryForDisplay(): string;
1469
+ /**
1470
+ * The cache lock withoutOverlapping() holds: `framework/schedule-` and the sha1 of the expression and the command,
1471
+ * or of the name for call() and job() events (Laravel's mutexName()). schedule:clear-cache deletes it.
1472
+ */
1473
+ mutexName(): string;
912
1474
  isDue(now: Date): boolean;
913
1475
  run(): Promise<void>;
914
1476
  }
@@ -987,6 +1549,8 @@ interface PendingMail {
987
1549
  cc(recipients: MailRecipient | MailRecipient[]): this;
988
1550
  bcc(recipients: MailRecipient | MailRecipient[]): this;
989
1551
  send(mailable: Mailable): Promise<SentMessage | undefined>;
1552
+ /** Sends at once, even when the mailable is queueable (Laravel's sendNow()). A fake resolves undefined. */
1553
+ sendNow(mailable: Mailable): Promise<SentMessage | undefined>;
990
1554
  queue(mailable: Mailable): Promise<void>;
991
1555
  later(delaySeconds: number, mailable: Mailable): Promise<void>;
992
1556
  }
@@ -994,6 +1558,8 @@ interface Mailer {
994
1558
  to(recipients: MailRecipient | MailRecipient[]): PendingMail;
995
1559
  /** Sends to the recipients given in the mailable's envelope. Queues it if the mailable is queueable. */
996
1560
  send(mailable: Mailable): Promise<SentMessage | undefined>;
1561
+ /** Sends to the envelope's recipients at once, even when the mailable is queueable (Laravel's sendNow()). */
1562
+ sendNow(mailable: Mailable): Promise<SentMessage | undefined>;
997
1563
  queue(mailable: Mailable): Promise<void>;
998
1564
  }
999
1565
  interface MailManager extends Mailer {
@@ -1029,6 +1595,28 @@ interface NotificationDispatcher {
1029
1595
  extend(channel: string, factory: () => NotificationChannel): void;
1030
1596
  }
1031
1597
  declare const NotificationDispatcher: Token<NotificationDispatcher>;
1598
+ /**
1599
+ * A stored database notification (Laravel's DatabaseNotification model): one row of the `notifications` table, with
1600
+ * its snake_case columns. `user.notifications()`, `unreadNotifications()` and `readNotifications()` query these,
1601
+ * newest first.
1602
+ */
1603
+ interface DatabaseNotification extends ModelInstance {
1604
+ /** A UUID. */
1605
+ readonly id: string;
1606
+ /** The notification's class name. */
1607
+ readonly type: string;
1608
+ /** What the notification's toDatabase() (or toArray()) returned. */
1609
+ readonly data: Record<string, unknown>;
1610
+ read_at: Date | null;
1611
+ readonly created_at: Date | null;
1612
+ readonly updated_at: Date | null;
1613
+ /** Sets read_at to now and saves, unless it is already read. */
1614
+ markAsRead(): Promise<void>;
1615
+ /** Clears read_at and saves, unless it is already unread. */
1616
+ markAsUnread(): Promise<void>;
1617
+ read(): boolean;
1618
+ unread(): boolean;
1619
+ }
1032
1620
 
1033
1621
  interface Lock {
1034
1622
  /** Tries once. Returns whether it was acquired. */
@@ -1068,6 +1656,18 @@ interface CacheManager extends CacheRepository {
1068
1656
  extend(driver: string, factory: (config: Record<string, unknown>) => CacheRepository): void;
1069
1657
  }
1070
1658
  declare const CacheManager: Token<CacheManager>;
1659
+ /** Laravel's RateLimiter: hits per key, kept in the default cache store. */
1660
+ interface RateLimiter {
1661
+ tooManyAttempts(key: string, maxAttempts: number): Promise<boolean>;
1662
+ /** Adds a hit; the window starts at the first hit and lasts `decaySeconds` (default 60). Returns the hit count. */
1663
+ hit(key: string, decaySeconds?: number): Promise<number>;
1664
+ attempts(key: string): Promise<number>;
1665
+ remaining(key: string, maxAttempts: number): Promise<number>;
1666
+ /** Seconds until the key's window resets. */
1667
+ availableIn(key: string): Promise<number>;
1668
+ clear(key: string): Promise<void>;
1669
+ }
1670
+ declare const RateLimiter: Token<RateLimiter>;
1071
1671
 
1072
1672
  type ListenerClass<E> = Class<{
1073
1673
  handle(event: E): unknown;
@@ -1124,38 +1724,99 @@ interface FilesystemManager extends Filesystem {
1124
1724
  }
1125
1725
  declare const FilesystemManager: Token<FilesystemManager>;
1126
1726
 
1127
- /** The Inertia page object (protocol v2). */
1727
+ /** Infinite-scroll metadata for one prop (page.scrollProps[path]). */
1728
+ interface InertiaScrollProp {
1729
+ pageName: string;
1730
+ previousPage: string | number | null;
1731
+ nextPage: string | number | null;
1732
+ currentPage: string | number | null;
1733
+ reset: boolean;
1734
+ }
1735
+ /** A once prop the client keeps between visits (page.onceProps[key]). `expiresAt` is epoch milliseconds. */
1736
+ interface InertiaOnceProp {
1737
+ prop: string;
1738
+ expiresAt: number | null;
1739
+ }
1740
+ /**
1741
+ * The Inertia page object (protocol v3, @inertiajs/core 3.x). Only component, props, url and version are always
1742
+ * present; the other fields are left out when empty or false.
1743
+ */
1128
1744
  interface InertiaPage {
1129
1745
  component: string;
1130
1746
  props: Record<string, unknown>;
1747
+ /** Path and query, never absolute: '/posts?page=2'. */
1131
1748
  url: string;
1132
- version: string | null;
1133
- encryptHistory?: boolean;
1134
- clearHistory?: boolean;
1749
+ /** '' when the app has no asset version. */
1750
+ version: string;
1751
+ sharedProps?: string[];
1135
1752
  mergeProps?: string[];
1753
+ prependProps?: string[];
1754
+ deepMergeProps?: string[];
1755
+ /** '<prop path>.<key field>', e.g. 'posts.data.id'. */
1756
+ matchPropsOn?: string[];
1757
+ /** Group name → prop paths loaded after the first render. */
1136
1758
  deferredProps?: Record<string, string[]>;
1759
+ rescuedProps?: string[];
1760
+ scrollProps?: Record<string, InertiaScrollProp>;
1761
+ onceProps?: Record<string, InertiaOnceProp>;
1762
+ clearHistory?: true;
1763
+ encryptHistory?: true;
1764
+ flash?: Record<string, unknown>;
1765
+ preserveFragment?: true;
1137
1766
  }
1138
1767
  interface InertiaResponse extends Responsable {
1139
1768
  with(key: string | Record<string, unknown>, value?: unknown): this;
1140
1769
  withViewData(key: string | Record<string, unknown>, value?: unknown): this;
1770
+ rootView(view: string): this;
1771
+ /** Flash data for the next page (page.flash), stored in the session. */
1772
+ flash(key: string | Record<string, unknown>, value?: unknown): this;
1141
1773
  }
1142
1774
  type PropCallback<T = unknown> = () => T | Promise<T>;
1775
+ /** The SSR result spliced into the root view: the `head` tags and the rendered `body`. */
1776
+ interface InertiaSsrResponse {
1777
+ head: string;
1778
+ body: string;
1779
+ }
1780
+ /** Sends a page to the SSR server. Resolves to undefined when SSR is off, unreachable or failing. */
1781
+ interface InertiaSsrGateway {
1782
+ dispatch(page: InertiaPage): Promise<InertiaSsrResponse | undefined>;
1783
+ }
1784
+ declare const InertiaSsrGateway: Token<InertiaSsrGateway>;
1143
1785
  interface InertiaFactory {
1144
1786
  render(component: string, props?: Record<string, unknown>): InertiaResponse;
1145
1787
  share(key: string | Record<string, unknown>, value?: unknown): void;
1788
+ /** A shared once prop: sent on the first visit, then kept by the client. */
1789
+ shareOnce(key: string, callback: PropCallback): void;
1146
1790
  getShared(key?: string): unknown;
1147
- version(version: string | (() => string | Promise<string>)): void;
1791
+ flushShared(): void;
1792
+ version(version: string | null | (() => string | null | Promise<string | null>)): void;
1793
+ getVersion(): Promise<string>;
1794
+ setRootView(view: string): void;
1148
1795
  /** Only evaluated on partial reloads that ask for it. */
1149
1796
  optional<T>(callback: PropCallback<T>): unknown;
1150
1797
  /** Loaded in a follow-up request after the first render. */
1151
1798
  defer<T>(callback: PropCallback<T>, group?: string): unknown;
1152
1799
  /** Always included, even in partial reloads. */
1153
1800
  always<T>(value: T | PropCallback<T>): unknown;
1154
- /** Merged with the existing client-side value instead of replacing it. */
1801
+ /** Appended to the existing client-side value instead of replacing it. */
1155
1802
  merge<T>(value: T | PropCallback<T>): unknown;
1156
- /** 409 + X-Inertia-Location for external redirects. */
1803
+ /** Deep-merged with the existing client-side value. */
1804
+ deepMerge<T>(value: T | PropCallback<T>): unknown;
1805
+ /** Resolved once, then remembered by the client. */
1806
+ once<T>(callback: PropCallback<T>): unknown;
1807
+ /** Infinite scroll over a paginator: merged page by page, with scroll metadata. */
1808
+ scroll<T>(value: T | PropCallback<T>, wrapper?: string): unknown;
1809
+ /** Flash data for the next page (page.flash), stored in the session. */
1810
+ flash(key: string | Record<string, unknown>, value?: unknown): this;
1811
+ encryptHistory(encrypt?: boolean): void;
1812
+ /** The next page tells the client to clear its encrypted history. */
1813
+ clearHistory(): void;
1814
+ /** The next page keeps the URL fragment of the request that redirected to it. */
1815
+ preserveFragment(): void;
1816
+ /** 409 + X-Inertia-Location for Inertia requests, a plain 302 otherwise. */
1157
1817
  location(url: string): Response;
1158
- setRootView(view: string): void;
1818
+ /** Redirect back (Inertia.flash('saved', true).back()). */
1819
+ back(fallback?: string, status?: number): RedirectResponse;
1159
1820
  }
1160
1821
  declare const InertiaFactory: Token<InertiaFactory>;
1161
1822
 
@@ -1175,11 +1836,18 @@ interface LiveSnapshot {
1175
1836
  }
1176
1837
  interface LiveEffects {
1177
1838
  html?: string;
1839
+ /** Browser events from this.dispatch(); `self` keeps one on this component, `to` sends it to one component name. */
1178
1840
  dispatches?: Array<{
1179
1841
  name: string;
1180
- params: unknown[];
1842
+ params: Record<string, unknown>;
1843
+ self?: true;
1844
+ to?: string;
1181
1845
  }>;
1846
+ /** Events this component listens to (@On, static listeners); sent with the first render. */
1847
+ listeners?: string[];
1182
1848
  redirect?: string;
1849
+ /** Follow `redirect` with o:navigate instead of a full page load. */
1850
+ redirectUsingNavigate?: true;
1183
1851
  returns?: unknown[];
1184
1852
  }
1185
1853
  interface LiveUpdateRequest {
@@ -1201,12 +1869,17 @@ interface LiveUpdateResponse {
1201
1869
  }
1202
1870
  interface LiveManager {
1203
1871
  register(component: Class<unknown>, name?: string): void;
1204
- /** Server-renders the first HTML (snapshot embedded). */
1205
- mount(component: string | Class<unknown>, params?: Record<string, unknown>): Promise<string>;
1872
+ /** Server-renders the first HTML (snapshot embedded). `key` identifies a child inside its parent (o:key). */
1873
+ mount(component: string | Class<unknown>, params?: Record<string, unknown>, key?: string): Promise<string>;
1206
1874
  /** Checks checksums and CSRF, then applies updates and calls, re-renders and returns new snapshots. */
1207
1875
  update(request: LiveUpdateRequest): Promise<LiveUpdateResponse>;
1876
+ /**
1877
+ * A full-page component (Route.get('/counter', Counter)): mounts `component` (a component instance) with the current route's parameters and
1878
+ * returns the response, its layout view or a redirect.
1879
+ */
1880
+ page(component: object): Promise<unknown>;
1208
1881
  isLiveRequest(request: HttpRequest): boolean;
1209
1882
  }
1210
1883
  declare const LiveManager: Token<LiveManager>;
1211
1884
 
1212
- export { type AbilityCallback, type Abstract, type ActionMethods, type Address, Application, type Arrayable, type Attachment, AuthFactory, type Authenticatable, type AuthenticationError, type Batch, BatchRepository, type BodyInit, BusDispatcher, CacheManager, type CacheRepository, type Class, ClassRegistry, type ClosureCommand, type Command, type CommandContext, type Concrete, type ConfigCallbacks, ConfigRepository, ConsoleKernel, Container, type Content, type ControllerAction, type Cookie, CookieJar, type Credentials, CurrentRoute, type DatabaseConnection, DatabaseManager, type DriverName, Encrypter, type Enumerable, type Envelope, type ErrorKind, EventDispatcher, ExceptionCallbacks, ExceptionHandler, type ExceptionsConfigurator, type Factory, type FailedJob, FailedJobProvider, type Filesystem, FilesystemManager, Gate, type Guard, Hasher, type HeadersInit, type Htmlable, HttpKernel, HttpRequest, InertiaFactory, type InertiaPage, type InertiaResponse, type Job, type Jsonable, type Listener, type ListenerClass, type LiveEffects, LiveManager, type LiveSnapshot, type LiveUpdateRequest, type LiveUpdateResponse, type Lock, type LogLevel, LogManager, type Logger, MailManager, type MailRecipient, type MailTransport, type Mailable, type Mailer, type MessageBag, type Middleware, MiddlewareCallbacks, type MiddlewareClass, type MiddlewareConfigurator, type MiddlewareReference, type ModelInstance, type ModelNotFoundError, type ModelStatic, type MustVerifyEmail, type Next, type Notifiable, type Notification, type NotificationChannel, NotificationDispatcher, type Operator, type OptionValue, type OrielError, type OutgoingMessage, PasswordBroker, type PasswordStatus, type PendingBatch, type PendingBatchOptions, type PendingChain, type PendingMail, type Pipe, type PipeClosure, type PipeNext, type Pipeline, PipelineFactory, type PropCallback, type PutOptions, type QueryBuilder, type Queue, type QueueJob, QueueManager, type QueuePayload, type RedirectResponse, Redirector, type ResourceOptions, type Responsable, ResponseFactory, type Route, type RouteAction, type RouteClosure, RouteModelResolver, type RouteRegistrar, Router, RoutingPaths, type Row, type RuleCallback, type Rules, Schedule, type ScheduledEvent, type SentMessage, type ServiceProvider, type ServiceProviderClass, Session, type SessionHandler, type ShouldQueue, type StatefulGuard, type Token, type UploadedFile, UrlGenerator, type UserProvider, type ValidationError, ValidationFactory, type ValidationRule, type Validator, type View, ViewFactory, token };
1885
+ export { type AbilityCallback, type Abstract, type ActionMethods, type Address, Application, type Arrayable, type Attachment, AuthFactory, type Authenticatable, type AuthenticationError, type Batch, BatchRepository, type BodyInit, BusDispatcher, CacheManager, type CacheRepository, type Class, ClassRegistry, type ClosureCommand, type Command, type CommandContext, type Concrete, type ConfigCallbacks, ConfigRepository, ConsoleKernel, Container, type Content, type ControllerAction, type Cookie, CookieJar, type Credentials, CurrentRoute, type DatabaseConnection, DatabaseManager, type DatabaseNotification, type DriverName, Encrypter, type Enumerable, type Envelope, type ErrorKind, EventDispatcher, ExceptionCallbacks, ExceptionHandler, type ExceptionsConfigurator, type Factory, type FailedJob, FailedJobProvider, type Filesystem, FilesystemManager, Gate, type Guard, Hasher, type HeadersInit, type Htmlable, HttpKernel, HttpRequest, type InValue, InertiaFactory, type InertiaOnceProp, type InertiaPage, type InertiaResponse, type InertiaScrollProp, InertiaSsrGateway, type InertiaSsrResponse, type InferRuleType, type InferValidatedType, type InvokableClass, type Job, type Jsonable, type Listener, type ListenerClass, type LiveEffects, LiveManager, type LiveSnapshot, type LiveUpdateRequest, type LiveUpdateResponse, type Lock, type LogLevel, LogManager, type Logger, MailManager, type MailRecipient, type MailTransport, type Mailable, type Mailer, type MessageBag, type Middleware, MiddlewareCallbacks, type MiddlewareClass, type MiddlewareConfigurator, type MiddlewareReference, type ModelInstance, type ModelNotFoundError, type ModelStatic, type MustVerifyEmail, type Next, type Notifiable, type Notification, type NotificationChannel, NotificationDispatcher, type NumericValue, type Operator, type OptionValue, type OrielError, type OutgoingMessage, PaginationState, PasswordBroker, type PasswordStatus, type PendingBatch, type PendingBatchOptions, type PendingChain, type PendingMail, type Pipe, type PipeClosure, type PipeNext, type Pipeline, PipelineFactory, type PropCallback, type PutOptions, type QueryBuilder, type Queue, type QueueJob, QueueManager, type QueuePayload, RateLimiter, type RedirectResponse, Redirector, type ResourceOptions, type Responsable, ResponseFactory, type Route, type RouteAction, type RouteArguments, type RouteClosure, type RouteList, RouteModelResolver, type RouteName, type RouteParameter, type RouteParameters, type RouteRegistrar, Router, RoutingPaths, type Row, type RuleCallback, type RuleParameterList, type RuleTyping, type Rules, Schedule, type ScheduleHook, type ScheduledEvent, type SentMessage, type ServiceProvider, type ServiceProviderClass, Session, type SessionHandler, type ShouldQueue, type StatefulGuard, type Token, type TypedValidationRule, type UploadedFile, UrlGenerator, type UserProvider, type ValidationError, ValidationFactory, type ValidationRule, type ValidationRuleTypes, type Validator, type View, ViewFactory, token };