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

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (88) hide show
  1. package/NOTICE +7 -0
  2. package/README.md +10 -1
  3. package/TRADEMARKS.md +33 -0
  4. package/dist/{chunk-WI7E7Q46.js → chunk-24673JQF.js} +8 -4
  5. package/dist/chunk-24673JQF.js.map +1 -0
  6. package/dist/{chunk-K6MAA3RM.js → chunk-HTJKT2R2.js} +9 -1
  7. package/dist/chunk-HTJKT2R2.js.map +1 -0
  8. package/dist/chunk-KDE5BLI3.js +8776 -0
  9. package/dist/chunk-KDE5BLI3.js.map +1 -0
  10. package/dist/chunk-MURTCTRH.js +3253 -0
  11. package/dist/chunk-MURTCTRH.js.map +1 -0
  12. package/dist/contracts.d.ts +852 -168
  13. package/dist/contracts.js +9 -1
  14. package/dist/index.d-WQpfdIbG.d.ts +630 -0
  15. package/dist/index.d.ts +3015 -5160
  16. package/dist/index.js +7628 -2640
  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 +654 -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 +371 -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/export.md +93 -0
  46. package/docs/facades.md +278 -0
  47. package/docs/hashing.md +118 -0
  48. package/docs/helpers.md +1281 -0
  49. package/docs/http-tests.md +386 -0
  50. package/docs/inertia.md +485 -0
  51. package/docs/installation.md +219 -0
  52. package/docs/lifecycle.md +234 -0
  53. package/docs/live-tests.md +226 -0
  54. package/docs/live.md +910 -0
  55. package/docs/logging.md +255 -0
  56. package/docs/mail.md +619 -0
  57. package/docs/middleware.md +385 -0
  58. package/docs/migrations.md +416 -0
  59. package/docs/mocking.md +264 -0
  60. package/docs/navigation.json +277 -0
  61. package/docs/notifications.md +225 -0
  62. package/docs/pagination.md +247 -0
  63. package/docs/passwords.md +207 -0
  64. package/docs/providers.md +187 -0
  65. package/docs/queries.md +600 -0
  66. package/docs/queues.md +330 -0
  67. package/docs/requests.md +533 -0
  68. package/docs/responses.md +444 -0
  69. package/docs/routing.md +738 -0
  70. package/docs/scheduling.md +277 -0
  71. package/docs/seeding.md +122 -0
  72. package/docs/session.md +409 -0
  73. package/docs/starter-kits.md +399 -0
  74. package/docs/storage.md +192 -0
  75. package/docs/structure.md +264 -0
  76. package/docs/testing.md +165 -0
  77. package/docs/time-travel.md +138 -0
  78. package/docs/validation.md +1792 -0
  79. package/docs/verification.md +152 -0
  80. package/docs/views.md +566 -0
  81. package/docs/vite.md +400 -0
  82. package/package.json +37 -30
  83. package/dist/chunk-AI2RFMBT.js +0 -745
  84. package/dist/chunk-AI2RFMBT.js.map +0 -1
  85. package/dist/chunk-BZPCRKFQ.js +0 -2941
  86. package/dist/chunk-BZPCRKFQ.js.map +0 -1
  87. package/dist/chunk-K6MAA3RM.js.map +0 -1
  88. package/dist/chunk-WI7E7Q46.js.map +0 -1
@@ -0,0 +1,1586 @@
1
+ import { BusDispatcher, Job, PendingBatchOptions, Class, PendingChain, PendingBatch, Batch, EventDispatcher, Listener, MailManager, Mailable, Address, MailRecipient, Mailer, PendingMail, SentMessage, MailTransport, NotificationDispatcher, Notifiable, Notification, NotificationChannel, QueueManager, QueuePayload, Queue, QueueJob, FilesystemManager, Filesystem, PutOptions, UploadedFile, Application, Session, View, Authenticatable, Container, AuthFactory, InertiaPage, ServiceProvider, ServiceProviderClass, DatabaseManager, ModelInstance, Row, Encrypter, Token, ExceptionHandler, ViewFactory, RouteName, RouteArguments, Rules, InferValidatedType, MessageBag, LiveSnapshot, LiveEffects, OrielError, ErrorKind, Htmlable, LiveManager, HttpRequest, LiveUpdateRequest, LiveUpdateResponse, MiddlewareClass, Router } from './contracts.js';
2
+ import { S as ServiceProvider$1 } from './index.d-WQpfdIbG.js';
3
+
4
+ /** A date the tests travel to: a Date, an ISO string or milliseconds since the epoch. */
5
+ type TravelDate = Date | string | number;
6
+ /**
7
+ * Laravel's travelTo(): the clock stands at `date` (new Date(), Date.now() and now() all read it) until travelBack().
8
+ * With a callback, it runs there and the clock travels back after it; its result is returned.
9
+ */
10
+ declare function travelTo(date: TravelDate): void;
11
+ declare function travelTo<R>(date: TravelDate, callback: (date: Date) => R): R;
12
+ /** Laravel's travelBack(): the real clock again. Returns the real time. */
13
+ declare function travelBack(): Date;
14
+ /** Laravel's freezeTime(): holds the clock where it is now. Returns that time, or the callback's result. */
15
+ declare function freezeTime(): Date;
16
+ declare function freezeTime<R>(callback: (date: Date) => R): R;
17
+ /** Laravel's freezeSecond(): freezeTime() at the start of the current second. */
18
+ declare function freezeSecond(): Date;
19
+ declare function freezeSecond<R>(callback: (date: Date) => R): R;
20
+ /** Laravel's travel(5).minutes(): moves the clock on (a negative value moves it back) from where it stands. */
21
+ declare function travel(value: number): Wormhole;
22
+ /**
23
+ * Laravel's Wormhole: each unit moves the clock by `value` of it (months and years overflow as Carbon's do: 31 January
24
+ * plus a month is 3 March), in UTC. With a callback, it runs there, the clock travels back after it, and its result is
25
+ * returned. JavaScript dates hold milliseconds, so there are no microseconds.
26
+ */
27
+ declare class Wormhole {
28
+ #private;
29
+ readonly value: number;
30
+ constructor(value: number);
31
+ millisecond(): void;
32
+ millisecond<R>(callback: () => R): R;
33
+ milliseconds(): void;
34
+ milliseconds<R>(callback: () => R): R;
35
+ second(): void;
36
+ second<R>(callback: () => R): R;
37
+ seconds(): void;
38
+ seconds<R>(callback: () => R): R;
39
+ minute(): void;
40
+ minute<R>(callback: () => R): R;
41
+ minutes(): void;
42
+ minutes<R>(callback: () => R): R;
43
+ hour(): void;
44
+ hour<R>(callback: () => R): R;
45
+ hours(): void;
46
+ hours<R>(callback: () => R): R;
47
+ day(): void;
48
+ day<R>(callback: () => R): R;
49
+ days(): void;
50
+ days<R>(callback: () => R): R;
51
+ week(): void;
52
+ week<R>(callback: () => R): R;
53
+ weeks(): void;
54
+ weeks<R>(callback: () => R): R;
55
+ month(): void;
56
+ month<R>(callback: () => R): R;
57
+ months(): void;
58
+ months<R>(callback: () => R): R;
59
+ year(): void;
60
+ year<R>(callback: () => R): R;
61
+ years(): void;
62
+ years<R>(callback: () => R): R;
63
+ /** Laravel's Wormhole::back(). */
64
+ static back(): Date;
65
+ }
66
+
67
+ /**
68
+ * Laravel's PendingCommand: `await t.artisan('inspire').expectsOutput('…').assertExitCode(0)`.
69
+ * It runs through ConsoleKernel.call() when awaited (or run()), then checks every expectation against the
70
+ * buffered output (stdout then stderr, as ConsoleKernel.output() returns it) and the exit code.
71
+ *
72
+ * The result must be awaited (or run() called): unlike Laravel, where the command runs when the
73
+ * PendingCommand is destroyed, nothing runs here until then, so an un-awaited `t.artisan(...)` never runs
74
+ * and checks nothing.
75
+ */
76
+ declare class PendingCommand implements PromiseLike<number> {
77
+ private readonly app;
78
+ readonly command: string;
79
+ readonly parameters: Record<string, unknown>;
80
+ private readonly checks;
81
+ private result;
82
+ constructor(app: Application, command: string, parameters?: Record<string, unknown>);
83
+ /** A line of output equals `line` exactly; with no argument, the command printed something. */
84
+ expectsOutput(line?: string): this;
85
+ /** No line equals `line`; with no argument, the command printed nothing at all. */
86
+ doesntExpectOutput(line?: string): this;
87
+ expectsOutputToContain(text: string): this;
88
+ doesntExpectOutputToContain(text: string): this;
89
+ assertExitCode(code: number): this;
90
+ assertNotExitCode(code: number): this;
91
+ assertSuccessful(): this;
92
+ assertOk(): this;
93
+ assertFailed(): this;
94
+ /** Runs the command once and checks the expectations; resolves to the exit code. */
95
+ run(): Promise<number>;
96
+ then<R1 = number, R2 = never>(onfulfilled?: ((value: number) => R1 | PromiseLike<R1>) | null, onrejected?: ((reason: unknown) => R2 | PromiseLike<R2>) | null): Promise<R1 | R2>;
97
+ private execute;
98
+ }
99
+
100
+ /** A table name, or a model (its table, and its connection when it has one). */
101
+ type TableOrModel = string | ModelInstance;
102
+
103
+ /** Laravel's JSON structure: `['id', { author: ['name'] }]`, and `'*'` for "every element". */
104
+ type JsonStructure = Array<string | {
105
+ [key: string]: JsonStructure;
106
+ }> | {
107
+ [key: string]: JsonStructure;
108
+ };
109
+
110
+ type Json = unknown;
111
+ type Scope<T extends AssertableJson> = (json: T) => unknown;
112
+ /**
113
+ * Laravel's Illuminate\Testing\Fluent\AssertableJson: fluent, scoped assertions over decoded JSON. Inside a scope
114
+ * (has(key, callback), first(), each()) every property must be interacted with, or etc() must be called.
115
+ */
116
+ declare class AssertableJson {
117
+ protected readonly props: Json;
118
+ protected readonly path: string | undefined;
119
+ protected interactedKeys: string[];
120
+ constructor(props: Json, path?: string | undefined);
121
+ static fromJson(json: Json): AssertableJson;
122
+ /** A child scope of the same class (subclasses override to keep their extra state out of scopes). */
123
+ protected newScope(props: Json, path: string): AssertableJson;
124
+ protected dotPath(key?: string): string;
125
+ /** The value at `key` in this scope, or the whole scope. */
126
+ protected prop(key?: string): Json;
127
+ /** A literal key of this scope wins over a dot path, like Laravel's Arr::get (keys such as 'items.0.name'). */
128
+ private hasOwnKey;
129
+ private exists;
130
+ protected interactsWith(key: string | number): void;
131
+ /** Every property of the scope was checked (called when a scope ends). */
132
+ interacted(): void;
133
+ /** Allow the properties this scope didn't check. */
134
+ etc(): this;
135
+ /** has('key'), has('key', 3), has('key', json => …), has('key', 3, first => …), or has(3) for the root size. */
136
+ has(key: string | number, length?: number | Scope<this>, callback?: Scope<this>): this;
137
+ /** hasAll(['a', 'b']) or hasAll({ items: 3 }). */
138
+ hasAll(keys: string | string[] | Record<string, number>): this;
139
+ hasAny(keys: string | string[]): this;
140
+ missing(key: string): this;
141
+ missingAll(keys: string | string[]): this;
142
+ /** count(3) checks this scope's size; count('items', 3) a property's. */
143
+ count(key: string | number, length?: number): this;
144
+ countBetween(key: string, min: number, max: number): this;
145
+ /** where('name', 'Ann'), or where('name', value => value.startsWith('A')). Objects compare ignoring key order. */
146
+ where(key: string, expected: unknown): this;
147
+ whereNot(key: string, expected: unknown): this;
148
+ whereNull(key: string): this;
149
+ whereNotNull(key: string): this;
150
+ whereAll(bindings: Record<string, unknown>): this;
151
+ /** whereType('id', 'integer'), whereType('name', 'string|null'), whereType('tags', ['array', 'null']). */
152
+ whereType(key: string, expected: string | string[]): this;
153
+ whereAllType(bindings: Record<string, string | string[]>): this;
154
+ /** The list contains every expected value (or one passing the callback); a string contains the substring. */
155
+ whereContains(key: string, expected: unknown): this;
156
+ protected scope(key: string, callback: Scope<this>): this;
157
+ first(callback: Scope<this>): this;
158
+ each(callback: Scope<this>): this;
159
+ when(condition: unknown, callback: (json: this) => unknown, otherwise?: (json: this) => unknown): this;
160
+ dump(key?: string): this;
161
+ toArray(): Json;
162
+ }
163
+
164
+ /** The page object of a response: the JSON body of an Inertia visit, or the page script of a first visit. */
165
+ declare function inertiaPageOf(response: TestResponse): InertiaPage;
166
+ /** Inertia's AssertableInertia: AssertableJson over the page props, plus the page component, url, version and flash. */
167
+ declare class AssertableInertia extends AssertableJson {
168
+ #private;
169
+ static fromTestResponse(response: TestResponse): AssertableInertia;
170
+ /** Scopes are plain AssertableJson: the page-level methods only make sense at the root. */
171
+ protected newScope(props: unknown, path: string): AssertableJson;
172
+ get page(): InertiaPage;
173
+ /** The component name; the page file must exist unless `shouldExist` is false (inertia.testing.ensure_pages_exist). */
174
+ component(value?: string, shouldExist?: boolean): this;
175
+ url(value: string): this;
176
+ version(value: string): this;
177
+ /** The flash data has `key` (dot paths allowed), equal to `expected` when given. */
178
+ hasFlash(key: string, ...expected: [] | [unknown]): this;
179
+ missingFlash(key: string): this;
180
+ static assertFlashHas(flash: Record<string, unknown>, key: string, ...expected: [] | [unknown]): void;
181
+ static assertFlashMissing(flash: Record<string, unknown>, key: string): void;
182
+ /**
183
+ * Requests the page again as a partial reload (only/except) and checks it is the same page. Uses the test's
184
+ * HTTP client, so the session and cookies carry over.
185
+ */
186
+ reload(callback?: (page: AssertableInertia) => unknown, only?: string | string[], except?: string | string[]): Promise<this>;
187
+ reloadOnly(only: string | string[], callback?: (page: AssertableInertia) => unknown): Promise<this>;
188
+ reloadExcept(except: string | string[], callback?: (page: AssertableInertia) => unknown): Promise<this>;
189
+ /** Loads the deferred props of every group (or the given groups) in one partial reload. */
190
+ loadDeferredProps(groupsOrCallback: string | string[] | ((page: AssertableInertia) => unknown), callback?: (page: AssertableInertia) => unknown): Promise<this>;
191
+ toArray(): Record<string, unknown>;
192
+ }
193
+
194
+ /** Laravel's CookieValuePrefix: hmac_sha1(name + 'v2', key) + '|' (41 characters), as Auth's EncryptCookies writes it. */
195
+ declare function cookiePrefix(name: string, key: Uint8Array): string;
196
+ /** What EncryptCookies puts in a browser cookie: encrypt(prefix + value, serialize: false). */
197
+ declare function encryptCookie(encrypter: Encrypter, name: string, value: string): string;
198
+ /** The plain value of an encrypted cookie, or undefined when it doesn't decrypt or its prefix is wrong. */
199
+ declare function decryptCookie(encrypter: Encrypter, name: string, value: string): string | undefined;
200
+ interface ResponseCookie {
201
+ name: string;
202
+ /** URI-decoded, still encrypted if the app encrypted it. */
203
+ value: string;
204
+ path?: string;
205
+ domain?: string;
206
+ maxAge?: number;
207
+ expires?: Date;
208
+ httpOnly: boolean;
209
+ secure: boolean;
210
+ sameSite?: string;
211
+ }
212
+ /** Max-Age <= 0 or an Expires in the past: the server is deleting the cookie. */
213
+ declare function isExpired(cookie: ResponseCookie, now?: number): boolean;
214
+ declare function responseCookies(response: Response): ResponseCookie[];
215
+ declare function cookieHeader(cookies: Map<string, string>): string;
216
+
217
+ /** Field → messages, as Http flashes them per bag: `errors: { [bag]: { field: string[] } }`. */
218
+ type ErrorMessages = Record<string, string[]>;
219
+ /** `'email'`, `['email', 'name']` or `{ email: 'must be valid' }` (message fragments). */
220
+ type ExpectedErrors = string | string[] | Record<string, string | string[]>;
221
+ /** What the HTTP client knows about the request that produced a response. */
222
+ interface ResponseContext {
223
+ /** The raw request sent to the kernel (redirect URLs are resolved against it). */
224
+ request?: Request;
225
+ /** The application that handled it. */
226
+ app?: Application;
227
+ /** The request's session after the response. */
228
+ session?: Session;
229
+ /** Views made while handling the request, in order. */
230
+ views?: View[];
231
+ /** The last error the exception handler rendered. */
232
+ exception?: unknown;
233
+ /** The client that sent the request (Inertia reloads reuse it, keeping the session and cookies). */
234
+ client?: HttpClient;
235
+ }
236
+ /** Laravel's TestResponse: a Response with its body already read, plus fluent assertions. */
237
+ declare class TestResponse {
238
+ readonly baseResponse: Response;
239
+ readonly content: string;
240
+ readonly context: ResponseContext;
241
+ private decoded;
242
+ constructor(baseResponse: Response, content: string, context?: ResponseContext);
243
+ /** Reads the body once, so every assertion is synchronous. */
244
+ static from(response: Response, context?: ResponseContext): Promise<TestResponse>;
245
+ get status(): number;
246
+ get headers(): Headers;
247
+ /** The error the exception handler rendered for this request, if any. */
248
+ get exception(): unknown;
249
+ getContent(): string;
250
+ /** The decoded JSON body, or the value at a dot path (`data.0.id`). */
251
+ json<T = unknown>(path?: string): T;
252
+ dump(path?: string): this;
253
+ assertStatus(status: number): this;
254
+ assertOk(): this;
255
+ assertCreated(): this;
256
+ assertAccepted(): this;
257
+ assertMovedPermanently(): this;
258
+ assertFound(): this;
259
+ assertNotModified(): this;
260
+ assertBadRequest(): this;
261
+ assertUnauthorized(): this;
262
+ assertPaymentRequired(): this;
263
+ assertForbidden(): this;
264
+ assertNotFound(): this;
265
+ assertMethodNotAllowed(): this;
266
+ assertNotAcceptable(): this;
267
+ assertRequestTimeout(): this;
268
+ assertConflict(): this;
269
+ assertGone(): this;
270
+ assertUnsupportedMediaType(): this;
271
+ assertUnprocessable(): this;
272
+ assertTooManyRequests(): this;
273
+ assertInternalServerError(): this;
274
+ assertServiceUnavailable(): this;
275
+ /** 204 (or `status`) with an empty body. */
276
+ assertNoContent(status?: number): this;
277
+ assertSuccessful(): this;
278
+ assertClientError(): this;
279
+ assertServerError(): this;
280
+ /** A redirect status (201, 301, 302, 303, 307, 308); with `uri`, the Location must match it. */
281
+ assertRedirect(uri?: string): this;
282
+ assertRedirectContains(uri: string): this;
283
+ /** Relative and absolute forms of the same URL are equal (both are resolved against the request URL). */
284
+ assertLocation(uri: string): this;
285
+ assertHeader(name: string, value?: string): this;
286
+ assertHeaderMissing(name: string): this;
287
+ /** Content-Disposition: attachment (optionally with this file name). */
288
+ assertDownload(filename?: string): this;
289
+ assertContent(value: string): this;
290
+ /** The content contains the value(s); values are HTML-escaped first unless `escape` is false (Laravel). */
291
+ assertSee(value: string | string[], escape?: boolean): this;
292
+ assertDontSee(value: string | string[], escape?: boolean): this;
293
+ assertSeeInOrder(values: string[], escape?: boolean): this;
294
+ /** Like assertSee, against the content with its tags stripped. */
295
+ assertSeeText(value: string | string[], escape?: boolean): this;
296
+ assertDontSeeText(value: string | string[], escape?: boolean): this;
297
+ assertSeeTextInOrder(values: string[], escape?: boolean): this;
298
+ /**
299
+ * The response JSON contains `data` (a subset match: extra keys in the response are fine), or fluent
300
+ * assertions: assertJson(json => json.has('data', 3).etc()).
301
+ */
302
+ assertJson(data: Record<string, unknown> | unknown[] | ((json: AssertableJson) => unknown)): this;
303
+ /**
304
+ * An Inertia page response, with optional fluent assertions over its props. An async callback (reload(),
305
+ * loadDeferredProps()) makes this return a promise: await it.
306
+ */
307
+ assertInertia(callback: (page: AssertableInertia) => Promise<unknown>): Promise<this>;
308
+ assertInertia(callback?: (page: AssertableInertia) => unknown): this;
309
+ /** The Inertia page object of this response. */
310
+ inertiaPage(): InertiaPage;
311
+ /** The page props, or one prop by dot path. */
312
+ inertiaProps<T = unknown>(key?: string): T;
313
+ /** Inertia flash data waiting in the session for the next page (after a redirect). */
314
+ assertInertiaFlash(key: string, ...expected: [] | [unknown]): this;
315
+ assertInertiaFlashMissing(key: string): this;
316
+ /** The response JSON equals `data` exactly (object key order is ignored). */
317
+ assertExactJson(data: unknown): this;
318
+ /** The value at `path` equals `expected` (strictly), or passes the predicate. */
319
+ assertJsonPath(path: string, expected: unknown): this;
320
+ assertJsonMissingPath(path: string): this;
321
+ /** Each key/value pair appears somewhere in the JSON (Laravel's assertJsonFragment). */
322
+ assertJsonFragment(data: Record<string, unknown>): this;
323
+ /** Passes when at least one pair of `data` is absent (Laravel's assertJsonMissing). */
324
+ assertJsonMissing(data: Record<string, unknown>): this;
325
+ /** `['id', { author: ['name'] }]`, `{ data: { '*': ['id'] } }`; without a structure, just checks it's JSON. */
326
+ assertJsonStructure(structure?: JsonStructure): this;
327
+ /** The JSON (or the value at `key`) has `count` elements. */
328
+ assertJsonCount(count: number, key?: string): this;
329
+ /** assertRedirect() to the URL of a named route (resolved with the app's UrlGenerator). */
330
+ assertRedirectToRoute(name: string, parameters?: unknown): this;
331
+ /** The JSON body has validation errors for these keys (and messages containing these fragments). */
332
+ assertJsonValidationErrors(errors: ExpectedErrors, responseKey?: string): this;
333
+ /** No validation errors in the JSON (or none for these keys). */
334
+ assertJsonMissingValidationErrors(keys?: string | string[], responseKey?: string): this;
335
+ /** No validation errors: JSON responses are checked in the body, others in the session. */
336
+ assertValid(keys?: string | string[], errorBag?: string, responseKey?: string): this;
337
+ /** Validation errors for these keys (message fragments match with "contains"): JSON body or session. */
338
+ assertInvalid(errors: ExpectedErrors, errorBag?: string, responseKey?: string): this;
339
+ /** The request's session after the response (flashed data is still there). */
340
+ session(): Session;
341
+ /** A key (with an optional value or predicate), several keys, or a { key: value } record. */
342
+ assertSessionHas(key: string | string[] | Record<string, unknown>, value?: unknown): this;
343
+ assertSessionHasAll(bindings: Record<string, unknown>): this;
344
+ assertSessionMissing(key: string | string[], value?: unknown): this;
345
+ /** Old input flashed with the redirect (withInput()). */
346
+ assertSessionHasInput(key: string | string[] | Record<string, unknown>, value?: unknown): this;
347
+ /**
348
+ * The session has errors in `errorBag`: any at all, these keys, or these exact messages (Laravel's rules).
349
+ * `format` is a ':message' template applied to the actual messages first.
350
+ */
351
+ assertSessionHasErrors(keys?: ExpectedErrors, format?: string, errorBag?: string): this;
352
+ assertSessionHasErrorsIn(errorBag: string, keys?: ExpectedErrors, format?: string): this;
353
+ /** No errors in any bag. */
354
+ assertSessionHasNoErrors(): this;
355
+ /** No errors in the bag (or none for these keys). */
356
+ assertSessionDoesntHaveErrors(keys?: string | string[], format?: string, errorBag?: string): this;
357
+ /** A cookie the response sets (the last Set-Cookie with that name). */
358
+ getCookie(name: string): ResponseCookie | undefined;
359
+ /** The cookie is set; with `value`, its (decrypted, unless `encrypted` is false) value matches. */
360
+ assertCookie(name: string, value?: string, encrypted?: boolean): this;
361
+ assertPlainCookie(name: string, value?: string): this;
362
+ assertCookieExpired(name: string): this;
363
+ assertCookieNotExpired(name: string): this;
364
+ assertCookieMissing(name: string): this;
365
+ /**
366
+ * The view the route returned. A request can make other views too (a mailable's, an error page), so this is the
367
+ * last view whose rendered HTML is the response body, else the last view made.
368
+ */
369
+ get original(): View | undefined;
370
+ assertViewIs(name: string): this;
371
+ /** The view received `key` (dot paths allowed), optionally with this value or passing this predicate. */
372
+ assertViewHas(key: string | string[] | Record<string, unknown>, value?: unknown): this;
373
+ assertViewHasAll(bindings: string[] | Record<string, unknown>): this;
374
+ assertViewMissing(key: string): this;
375
+ /** The data the view received (dot path), or all of it. */
376
+ viewData<T = unknown>(key?: string): T;
377
+ protected absolute(url: string): string;
378
+ protected excerpt(text?: string): string;
379
+ /** Adds the rendered exception (or the body) to a status failure, like Laravel does. */
380
+ protected statusMessage(message: string): string;
381
+ protected isJson(): boolean;
382
+ protected sessionErrors(errorBag: string): ErrorMessages;
383
+ private formatted;
384
+ /** Laravel's assertInvalid/assertJsonValidationErrors: each key present; each expected fragment contained in a message. */
385
+ private assertErrorsContain;
386
+ private ensureView;
387
+ private viewDataOf;
388
+ private decrypted;
389
+ private needles;
390
+ private inOrder;
391
+ }
392
+
393
+ type RequestData = Record<string, unknown>;
394
+ interface RequestOptions {
395
+ data?: RequestData;
396
+ headers?: Record<string, string>;
397
+ /** Send data as a JSON body (the *Json methods). */
398
+ json?: boolean;
399
+ }
400
+ /**
401
+ * Laravel's MakesHttpRequests state for one test: default headers, cookies, the session carried between
402
+ * requests, actingAs users and options, plus the dispatch itself.
403
+ */
404
+ declare class HttpClient {
405
+ protected readonly app: Application;
406
+ readonly headers: Record<string, string>;
407
+ /** Cookies to encrypt on send (withCookie) and to send as-is (withUnencryptedCookie, or captured from responses). */
408
+ readonly cookies: Map<string, {
409
+ value: string;
410
+ encrypt: boolean;
411
+ }>;
412
+ /** actingAs() users by guard name (undefined = the default guard). */
413
+ readonly users: Map<string | undefined, Authenticatable>;
414
+ followRedirects: boolean;
415
+ handleExceptions: boolean;
416
+ /** The guard actingAs(user, guard) made the default. */
417
+ defaultGuard: string | undefined;
418
+ /** Session attributes carried from one request to the next (Laravel keeps one session store per test). */
419
+ session: Record<string, unknown> | undefined;
420
+ /**
421
+ * withSession() and flushSession() since the last started session: applied to the stored session (the one the
422
+ * session cookie points to) once the next request starts it, so they win over what it holds, as in Laravel.
423
+ */
424
+ sessionChanges: Array<(session: Session) => void>;
425
+ /** from(url): the session's previous URL for the next request only (Laravel sets it once). */
426
+ previousUrl: string | undefined;
427
+ /** Requests whose actingAs users reached the guards (the AuthFactory they went through). */
428
+ private readonly actingAsApplied;
429
+ constructor(app: Application);
430
+ request(method: string, uri: string, options?: RequestOptions): Promise<TestResponse>;
431
+ /** Runs `fn` in a scope prepared like a request's (carried session, actingAs users), e.g. for assertAuthenticated(). */
432
+ inScope<T>(fn: (scope: Container) => T | Promise<T>): Promise<T>;
433
+ /**
434
+ * Runs `run` in a request scope like this client's requests have (a request for `method uri` bound, the carried
435
+ * session, actingAs users), then carries the session and the users on, as after a request. Live.test() runs its
436
+ * mount and updates through it.
437
+ */
438
+ withinRequest<T>(run: () => Promise<T>, method?: string, uri?: string): Promise<T>;
439
+ /** Runs the request through the app's real HttpKernel, in a request scope this client owns. */
440
+ protected send(request: Request): Promise<TestResponse>;
441
+ /** Prepares the request scope: recorders, the carried session and actingAs users. */
442
+ protected beforeRequest(scope: Container, context: ResponseContext): void;
443
+ /** Keeps the session for the next request, like Laravel's per-test session store, and the guards' users. */
444
+ protected afterRequest(_scope: Container, context: ResponseContext): Promise<void>;
445
+ /**
446
+ * Laravel's actingAs() sets the user on the guard once, so a logout (or a login as someone else) in the
447
+ * request sticks. Reads each actingAs guard back and forgets or replaces its user to match.
448
+ */
449
+ protected syncActingAs(auth: AuthFactory): Promise<void>;
450
+ /** Applies the pending withSession()/flushSession() changes once the session has loaded what it stored. */
451
+ protected applyOnStart(session: Session): void;
452
+ /** Applies the pending withSession()/flushSession() changes to the session, once. */
453
+ protected applyPending(session: Session): void;
454
+ /** The request's (scoped) Session, created now so the carried attributes are in place before StartSession. */
455
+ protected scopeSession(scope: Container): Session | undefined;
456
+ buildRequest(method: string, uri: string, options: RequestOptions): Request;
457
+ protected baseUrl(): string;
458
+ protected cookieHeader(): string;
459
+ /** Like a browser: cookies the app sets are sent back on later requests in the same test; deleted ones are dropped. */
460
+ protected rememberCookies(response: Response): void;
461
+ }
462
+ /** `{ user: { name: 'a' }, tags: ['x'] }` → `user[name]=a`, `tags[0]=x` (the PHP bracket form Http parses). */
463
+ declare function flatten(data: RequestData, prefix?: string): Array<[string, string | Blob]>;
464
+
465
+ /** The test runner's per-test hooks. Pass Vitest's: `{ beforeEach, afterEach }`. */
466
+ interface TestHooks {
467
+ beforeEach(fn: () => unknown): void;
468
+ afterEach(fn: () => unknown): void;
469
+ }
470
+ /** A Laravel-style trait (RefreshDatabase, …): setUp runs after the app boots; clean-up goes in beforeApplicationDestroyed. */
471
+ interface TestTrait {
472
+ setUp(test: InteractsWithApplication): void | Promise<void>;
473
+ }
474
+ interface BootOptions {
475
+ hooks?: TestHooks;
476
+ /** Extra traits for this file, like `use RefreshDatabase;`. */
477
+ uses?: TestTrait[];
478
+ }
479
+ type Callback = () => void | Promise<void>;
480
+ /**
481
+ * Laravel's TestCase lifecycle: a brand-new application for every test (createApplication() → boot → traits),
482
+ * and a full teardown after it, so no state survives from one test to the next.
483
+ */
484
+ declare abstract class InteractsWithApplication {
485
+ /** Set once in tests/TestCase.ts: `static override hooks = { beforeEach, afterEach }` (from vitest). */
486
+ static hooks?: TestHooks;
487
+ /** Traits this test case uses (Laravel's `use RefreshDatabase;`). */
488
+ readonly uses: TestTrait[];
489
+ private application;
490
+ private extraTraits;
491
+ private destroying;
492
+ /**
493
+ * Creates the test case and registers its setUp/tearDown as beforeEach/afterEach hooks.
494
+ * `const t = TestCase.boot()` at the top of a test file (or inside a describe block).
495
+ */
496
+ static boot<T extends InteractsWithApplication>(this: (new () => T) & {
497
+ hooks?: TestHooks;
498
+ }, options?: BootOptions): T;
499
+ /** The current test's application. */
500
+ get app(): Application;
501
+ /**
502
+ * A fresh application for one test. tests/TestCase.ts overrides this to call bootstrap/app's factory.
503
+ * The default builds one at basePath() with providers(), for package tests with no skeleton.
504
+ */
505
+ createApplication(): Promise<Application>;
506
+ /** Used by the default createApplication(). */
507
+ protected basePath(): string;
508
+ /** Used by the default createApplication(). */
509
+ protected providers(): Array<ServiceProvider | ServiceProviderClass>;
510
+ /** The variables applied (unless already set) before each application is created. */
511
+ protected environment(): Record<string, string>;
512
+ /** Adjust the fresh app before it boots, e.g. `app.make(ConfigRepository).set('mail.default', 'array')`. */
513
+ protected defineEnvironment(_app: Application): void | Promise<void>;
514
+ setUp(): Promise<void>;
515
+ tearDown(): Promise<void>;
516
+ /**
517
+ * Laravel's withoutVite(): in this test's requests vite([...]) and viteReactRefresh() render nothing, so feature
518
+ * tests of pages pass before `vite build` has written public/build/manifest.json.
519
+ */
520
+ withoutVite(): this;
521
+ /** Runs in tearDown(), before the application is thrown away (in registration order). */
522
+ beforeApplicationDestroyed(callback: Callback): void;
523
+ }
524
+
525
+ type Headers$1 = Record<string, string>;
526
+ /** Laravel's MakesHttpRequests: requests run in-process through the app's HttpKernel. State lasts for one test. */
527
+ declare abstract class MakesHttpRequests extends InteractsWithApplication {
528
+ private client;
529
+ /** The current test's HTTP client (created on first use). */
530
+ protected get http(): HttpClient;
531
+ protected createHttpClient(): HttpClient;
532
+ /** Live.test() runs in this test's request scope (Live reads the same token: no import between the packages). */
533
+ setUp(): Promise<void>;
534
+ tearDown(): Promise<void>;
535
+ withHeaders(headers: Headers$1): this;
536
+ withHeader(name: string, value: string): this;
537
+ withToken(token: string, type?: string): this;
538
+ withBasicAuth(username: string, password: string): this;
539
+ /** Removes the Authorization header, whatever case it was set with (header names are case-insensitive). */
540
+ withoutToken(): this;
541
+ /** Cookies are encrypted the way EncryptCookies expects when the app has an Encrypter. */
542
+ withCookies(cookies: Record<string, string>): this;
543
+ withCookie(name: string, value: string): this;
544
+ withUnencryptedCookies(cookies: Record<string, string>): this;
545
+ withUnencryptedCookie(name: string, value: string): this;
546
+ /** Follow redirects (always with GET, like Laravel) and return the final response. */
547
+ followingRedirects(): this;
548
+ /** Sets the Referer and the session's previous URL, so redirect()->back() goes there. */
549
+ from(url: string): this;
550
+ /** Puts data in the session for the following requests, over what the stored session holds (Laravel's withSession()). */
551
+ withSession(data: Record<string, unknown>): this;
552
+ /** Empties the session, the stored one included, so the next request starts with none (Laravel's flushSession()). */
553
+ flushSession(): this;
554
+ /** Every following request is authenticated as `user` on `guard` (which also becomes the default guard). */
555
+ actingAs(user: Authenticatable, guard?: string): this;
556
+ be(user: Authenticatable, guard?: string): this;
557
+ /** Errors escape from the request instead of being rendered (Laravel's withoutExceptionHandling()). */
558
+ withoutExceptionHandling(): this;
559
+ withExceptionHandling(): this;
560
+ /** The user is authenticated (after the requests so far: carried session and actingAs). */
561
+ assertAuthenticated(guard?: string): Promise<this>;
562
+ assertGuest(guard?: string): Promise<this>;
563
+ /** Same identifier and class as `user`. */
564
+ assertAuthenticatedAs(user: Authenticatable, guard?: string): Promise<this>;
565
+ protected isAuthenticated(guard?: string): Promise<boolean>;
566
+ get(uri: string, headers?: Headers$1): Promise<TestResponse>;
567
+ getJson(uri: string, headers?: Headers$1): Promise<TestResponse>;
568
+ post(uri: string, data?: RequestData, headers?: Headers$1): Promise<TestResponse>;
569
+ postJson(uri: string, data?: RequestData, headers?: Headers$1): Promise<TestResponse>;
570
+ put(uri: string, data?: RequestData, headers?: Headers$1): Promise<TestResponse>;
571
+ putJson(uri: string, data?: RequestData, headers?: Headers$1): Promise<TestResponse>;
572
+ patch(uri: string, data?: RequestData, headers?: Headers$1): Promise<TestResponse>;
573
+ patchJson(uri: string, data?: RequestData, headers?: Headers$1): Promise<TestResponse>;
574
+ delete(uri: string, data?: RequestData, headers?: Headers$1): Promise<TestResponse>;
575
+ deleteJson(uri: string, data?: RequestData, headers?: Headers$1): Promise<TestResponse>;
576
+ options(uri: string, data?: RequestData, headers?: Headers$1): Promise<TestResponse>;
577
+ head(uri: string, headers?: Headers$1): Promise<TestResponse>;
578
+ /** A JSON request with any verb; GET/HEAD data goes into the query string. */
579
+ json(method: string, uri: string, data?: RequestData, headers?: Headers$1): Promise<TestResponse>;
580
+ /** Any verb with form data (Laravel's call()). */
581
+ call(method: string, uri: string, data?: RequestData, headers?: Headers$1): Promise<TestResponse>;
582
+ }
583
+
584
+ /** Laravel's InteractsWithDatabase: database assertions and seeding, plus the options RefreshDatabase reads. */
585
+ declare abstract class InteractsWithDatabase extends MakesHttpRequests {
586
+ /** Seed after RefreshDatabase/DatabaseMigrations migrate (Laravel's $seed). */
587
+ seed: boolean;
588
+ /** Seed with this seeder class instead of DatabaseSeeder (Laravel's $seeder). */
589
+ seeder: string | undefined;
590
+ /** Connections RefreshDatabase/DatabaseTransactions wrap in a transaction (undefined = the default connection). */
591
+ connectionsToTransact: Array<string | undefined>;
592
+ protected get database(): DatabaseManager;
593
+ assertDatabaseHas(table: TableOrModel, data: Row, connection?: string): Promise<this>;
594
+ assertDatabaseMissing(table: TableOrModel, data: Row, connection?: string): Promise<this>;
595
+ assertDatabaseCount(table: TableOrModel, count: number, connection?: string): Promise<this>;
596
+ assertDatabaseEmpty(table: TableOrModel, connection?: string): Promise<this>;
597
+ assertModelExists(model: ModelInstance): Promise<this>;
598
+ assertModelMissing(model: ModelInstance): Promise<this>;
599
+ assertSoftDeleted(table: TableOrModel, data?: Row, connection?: string, deletedAtColumn?: string): Promise<this>;
600
+ assertNotSoftDeleted(table: TableOrModel, data?: Row, connection?: string, deletedAtColumn?: string): Promise<this>;
601
+ /** Runs `db:seed` (with a seeder class name, like Laravel's $this->seed(UserSeeder::class)). */
602
+ runSeeder(seeder?: string): Promise<this>;
603
+ }
604
+
605
+ /** Laravel's InteractsWithConsole: `await t.artisan('cmd', { user: 1, '--queue': 'high' }).assertExitCode(0)`. */
606
+ declare abstract class InteractsWithConsole extends InteractsWithDatabase {
607
+ /** The command runs when the returned PendingCommand is awaited; without `await` it never runs. */
608
+ artisan(command: string, parameters?: Record<string, unknown>): PendingCommand;
609
+ }
610
+
611
+ /**
612
+ * Laravel's InteractsWithTime: `t.travelTo(date)`, `t.travel(5).minutes()`, `t.freezeTime()`, `t.travelBack()`.
613
+ * The functions of the same names do the same outside a test case. A test case's tearDown travels back, so each of its
614
+ * tests ends in the real time; with the plain functions, call `travelBack()` in your own `afterEach()` or pass a callback.
615
+ */
616
+ declare abstract class InteractsWithTime extends InteractsWithConsole {
617
+ travelTo(date: TravelDate): void;
618
+ travelTo<R>(date: TravelDate, callback: (date: Date) => R): R;
619
+ travel(value: number): Wormhole;
620
+ travelBack(): Date;
621
+ freezeTime(): Date;
622
+ freezeTime<R>(callback: (date: Date) => R): R;
623
+ freezeSecond(): Date;
624
+ freezeSecond<R>(callback: (date: Date) => R): R;
625
+ tearDown(): Promise<void>;
626
+ }
627
+
628
+ /**
629
+ * Laravel's TestCase. Extend it in tests/TestCase.ts (override createApplication() and set `static hooks`),
630
+ * then in each file: `const t = TestCase.boot()`, or `TestCase.boot({ uses: [RefreshDatabase] })`.
631
+ */
632
+ declare abstract class TestCase extends InteractsWithTime {
633
+ }
634
+
635
+ /**
636
+ * Laravel's phpunit.xml <env> block. Applied before every test's application is created; variables that are
637
+ * already set (the shell, CI, vitest.config) win, like phpunit's non-forced <env>.
638
+ */
639
+ declare const TESTING_ENVIRONMENT: Readonly<Record<string, string>>;
640
+ declare function applyEnvironment(values: Record<string, string>, env?: NodeJS.ProcessEnv): void;
641
+
642
+ /** The request scope's ViewFactory: records every view made, so TestResponse can assert on it (assertViewIs/Has). */
643
+ declare function recordingViewFactory(factory: ViewFactory, views: View[]): ViewFactory;
644
+ /**
645
+ * The request scope's ExceptionHandler: records the error it renders (for failure messages and
646
+ * withoutExceptionHandling()), then renders it as usual.
647
+ */
648
+ declare function recordingExceptionHandler(handler: ExceptionHandler, record: (error: unknown) => void): ExceptionHandler;
649
+ /**
650
+ * The request scope's AuthFactory for actingAs(): the users are put on the scope's guards the first time
651
+ * anything touches auth. That is after the kernel bound HttpRequest, so request.user() sees them too.
652
+ * `onApply` runs when that happens, so the client knows to read the guards back after the request.
653
+ */
654
+ declare function actingAsAuthFactory(auth: AuthFactory, users: Map<string | undefined, Authenticatable>, defaultGuard: string | undefined, onApply?: () => void): AuthFactory;
655
+
656
+ /** Options a test case may declare (InteractsWithDatabase declares them): Laravel's $seed, $seeder, $connectionsToTransact. */
657
+ interface DatabaseTestOptions {
658
+ seed?: boolean;
659
+ seeder?: string;
660
+ connectionsToTransact?: Array<string | undefined>;
661
+ /**
662
+ * Replaces the once-per-process `migrate:fresh` that RefreshDatabase runs on a file or server database, for a test
663
+ * case that must not wipe the whole database. It must leave the schema migrated, and seeded when seed/seeder ask
664
+ * for it. (Laravel's migrateFreshUsing() returns options for migrate:fresh; here it replaces the command.)
665
+ */
666
+ migrateFreshUsing?(): void | Promise<void>;
667
+ }
668
+ /** Laravel's RefreshDatabaseState: the schema is migrated once per process (per worker). */
669
+ declare const RefreshDatabaseState: {
670
+ migrated: boolean;
671
+ };
672
+ /** Runs a console command through the ConsoleKernel contract; a non-zero exit fails the test with its output. */
673
+ declare function runCommand(app: Application, command: string, parameters?: Record<string, unknown>): Promise<void>;
674
+ /** Laravel's usingInMemoryDatabase(): the default connection's database is ':memory:'. */
675
+ declare function usingInMemoryDatabase(app: Application): boolean;
676
+ /**
677
+ * Laravel's RefreshDatabase.
678
+ * - In-memory SQLite: every test's new application has an empty database, so it just runs `migrate`.
679
+ * - Otherwise: `migrate:fresh` once per process (or the test's own migrateFreshUsing()), then each test runs inside a
680
+ * transaction that is rolled back.
681
+ */
682
+ declare const RefreshDatabase: TestTrait;
683
+ /** Laravel's DatabaseMigrations: `migrate:fresh` before each test, `migrate:rollback` after it. */
684
+ declare const DatabaseMigrations: TestTrait;
685
+ /** Laravel's DatabaseTransactions: each test runs in a transaction that is rolled back (no migrations). */
686
+ declare const DatabaseTransactions: TestTrait;
687
+
688
+ /** What an assertion targets: a class (exact constructor), or a name (a string event, a class name or a registry name). */
689
+ type Target<T = unknown> = Class<T> | string;
690
+ /** A count, or a filter over the recorded items. */
691
+ type CountOrFilter<A extends unknown[]> = number | ((...args: A) => boolean);
692
+ /** Swaps the fake in through the facade machinery (`facade(token).swap(fake)`: an instance on the current container). */
693
+ declare function install<T extends object, F extends T>(token: Token<T>, fake: F): F;
694
+ declare function nameOf(target: Target | object): string;
695
+ /** A recorded object (or string event) matches a target: same constructor, or the same (class) name. */
696
+ declare function matches(item: unknown, target: Target): boolean;
697
+
698
+ /** One dispatch: the event object (or name) and its payload. */
699
+ interface DispatchedEvent {
700
+ event: object | string;
701
+ payload: unknown[];
702
+ }
703
+ type EventFilter<E> = (event: E, payload: unknown[]) => boolean;
704
+ /** A listener as assertListening() expects it: a class, a [class, method] pair, a closure, or Function for any closure. */
705
+ type ExpectedListener = Listener<never> | readonly [Class<object>, string] | FunctionConstructor;
706
+ /**
707
+ * Laravel's Event::fake(): records dispatched events instead of running listeners. With a list, only those
708
+ * events are faked and everything else reaches the original dispatcher (so model events keep working).
709
+ */
710
+ declare class EventFake implements EventDispatcher {
711
+ readonly dispatcher: EventDispatcher | undefined;
712
+ private readonly eventsToFake;
713
+ private eventsToDispatch;
714
+ readonly events: DispatchedEvent[];
715
+ constructor(dispatcher: EventDispatcher | undefined, eventsToFake?: Target[], eventsToDispatch?: Target[]);
716
+ /** Installs the fake (on the current container) and returns it: `const events = EventFake.fake([OrderShipped])`. */
717
+ static fake(eventsToFake?: Target | Target[]): EventFake;
718
+ /** Fakes every event except these. */
719
+ static fakeExcept(eventsToDispatch: Target | Target[]): EventFake;
720
+ private static original;
721
+ except(events: Target | Target[]): this;
722
+ listen<E>(events: Class<E> | string | Array<Class<E> | string>, listener: Listener<E>): void;
723
+ hasListeners(event: Class<unknown> | string): boolean;
724
+ dispatch(event: object | string, payload?: unknown[]): Promise<unknown[]>;
725
+ /** Faked events return undefined (never false), so halting model events such as `saving` still proceed. */
726
+ until(event: object | string, payload?: unknown[]): Promise<unknown>;
727
+ subscribe(subscriber: Class<{
728
+ subscribe(events: EventDispatcher): void;
729
+ }>): void;
730
+ forget(event: Class<unknown> | string): void;
731
+ /** Dispatched at least once; a number asserts the exact count; a function filters (event, payload). */
732
+ assertDispatched<E>(event: Class<E> | string, callback?: CountOrFilter<[E, unknown[]]>): void;
733
+ assertDispatchedTimes<E>(event: Class<E> | string, times?: number): void;
734
+ assertNotDispatched<E>(event: Class<E> | string, callback?: EventFilter<E>): void;
735
+ assertNothingDispatched(): void;
736
+ /**
737
+ * Laravel's assertListening(event, listener): the original dispatcher has that listener for the event (a class, a
738
+ * [class, method] pair, the same closure, or Function for any closure; wildcard listeners count for a string event).
739
+ * With only the event, any listener will do.
740
+ */
741
+ assertListening(event: Class<unknown> | string, listener?: ExpectedListener): void;
742
+ /** The recorded events (objects, or names for string events) that match. */
743
+ dispatched<E>(event: Class<E> | string, callback?: EventFilter<E>): E[];
744
+ hasDispatched(event: Class<unknown> | string): boolean;
745
+ /** The original dispatcher's listeners for the event, as registered, wildcard ones included for a string event. */
746
+ private listenersFor;
747
+ private shouldFake;
748
+ }
749
+
750
+ type Filter$3<J> = (job: J) => boolean;
751
+ /** What a faked Bus.batch([...]).dispatch() recorded (Laravel's PendingBatchFake): the options Bus would store, plus the jobs. */
752
+ interface BatchRecord extends PendingBatchOptions {
753
+ readonly id: string;
754
+ readonly jobs: Job[];
755
+ }
756
+ /**
757
+ * Laravel's Bus::fake(): records dispatch/dispatchSync/dispatchAfterResponse, chains and batches instead of
758
+ * running or queueing them. With a list, only those jobs are faked; others go to the original dispatcher.
759
+ */
760
+ declare class BusFake implements BusDispatcher {
761
+ readonly dispatcher: BusDispatcher | undefined;
762
+ private readonly jobsToFake;
763
+ private jobsToDispatch;
764
+ readonly commands: Job[];
765
+ readonly commandsSync: Job[];
766
+ readonly commandsAfterResponse: Job[];
767
+ readonly batches: BatchRecord[];
768
+ /** The rest of the chain, by the first job (Bus.chain([a, b, c]) records a with [b, c]). */
769
+ readonly chains: Map<Job, Job[]>;
770
+ constructor(dispatcher: BusDispatcher | undefined, jobsToFake?: Target[], jobsToDispatch?: Target[]);
771
+ static fake(jobsToFake?: Target | Target[]): BusFake;
772
+ static fakeExcept(jobsToDispatch: Target | Target[]): BusFake;
773
+ private static original;
774
+ except(jobs: Target | Target[]): this;
775
+ dispatch(job: Job): Promise<unknown>;
776
+ dispatchSync(job: Job): Promise<unknown>;
777
+ dispatchAfterResponse(job: Job): void;
778
+ /**
779
+ * Bus's terminating callback flushes whatever BusDispatcher is bound, which is this fake: forward to the real
780
+ * dispatcher so the after-response jobs it didn't fake still run (Laravel runs them). Faked ones never run.
781
+ */
782
+ flushAfterResponse(): Promise<void>;
783
+ chain(jobs: Job[]): PendingChain;
784
+ batch(jobs: Job[]): PendingBatch;
785
+ findBatch(id: string): Promise<Batch | undefined>;
786
+ /** Dispatched in any way (dispatch, dispatchSync or dispatchAfterResponse); a number asserts the count. */
787
+ assertDispatched<J extends Job>(job: Target<J>, callback?: CountOrFilter<[J]>): void;
788
+ assertDispatchedTimes<J extends Job>(job: Target<J>, times?: number): void;
789
+ assertNotDispatched<J extends Job>(job: Target<J>, callback?: Filter$3<J>): void;
790
+ assertNothingDispatched(): void;
791
+ assertDispatchedSync<J extends Job>(job: Target<J>, callback?: CountOrFilter<[J]>): void;
792
+ assertNotDispatchedSync<J extends Job>(job: Target<J>, callback?: Filter$3<J>): void;
793
+ assertDispatchedAfterResponse<J extends Job>(job: Target<J>, callback?: CountOrFilter<[J]>): void;
794
+ assertNotDispatchedAfterResponse<J extends Job>(job: Target<J>, callback?: Filter$3<J>): void;
795
+ /** `[First, Second, new Third(1)]`: a dispatched First whose chain is exactly the rest (classes or equal instances). */
796
+ assertChained(expectedChain: Array<Target | Job>): void;
797
+ assertDispatchedWithoutChain<J extends Job>(job: Target<J>, callback?: Filter$3<J>): void;
798
+ /** A batch was dispatched that passes the check. */
799
+ assertBatched(callback: (batch: BatchRecord) => boolean): void;
800
+ assertBatchCount(count: number): void;
801
+ assertNothingBatched(): void;
802
+ dispatched<J extends Job>(job: Target<J>, callback?: Filter$3<J>): J[];
803
+ dispatchedSync<J extends Job>(job: Target<J>, callback?: Filter$3<J>): J[];
804
+ dispatchedAfterResponse<J extends Job>(job: Target<J>, callback?: Filter$3<J>): J[];
805
+ hasDispatched<J extends Job>(job: Target<J>): boolean;
806
+ private shouldFake;
807
+ private real;
808
+ }
809
+
810
+ /** One push: the job (or raw payload), where it went, and when. */
811
+ interface PushedJob {
812
+ job: Job | QueuePayload;
813
+ raw: boolean;
814
+ connection: string | undefined;
815
+ queue: string | undefined;
816
+ delay: number | undefined;
817
+ }
818
+ type Filter$2<J> = (job: J, queue: string | undefined, connection: string | undefined) => boolean;
819
+ /**
820
+ * Laravel's Queue::fake(): records push/later/pushRaw (on any connection) instead of queueing. Jobs that Bus
821
+ * dispatches to a queue land here too, because Bus resolves QueueManager when it queues.
822
+ */
823
+ declare class QueueFake implements QueueManager {
824
+ readonly manager: QueueManager | undefined;
825
+ private readonly jobsToFake;
826
+ private jobsToPush;
827
+ readonly jobs: PushedJob[];
828
+ constructor(manager: QueueManager | undefined, jobsToFake?: Target[], jobsToPush?: Target[]);
829
+ static fake(jobsToFake?: Target | Target[]): QueueFake;
830
+ static fakeExcept(jobsToPush: Target | Target[]): QueueFake;
831
+ private static original;
832
+ except(jobs: Target | Target[]): this;
833
+ /**
834
+ * A recording view of the connection (pushes remember its name). Its size()/clear() only see the jobs pushed
835
+ * through that connection name (no name: the jobs pushed without one, i.e. through the manager or connection()).
836
+ */
837
+ connection(name?: string): Queue;
838
+ push(job: Job, queue?: string): Promise<string>;
839
+ later(delaySeconds: number, job: Job, queue?: string): Promise<string>;
840
+ pushRaw(payload: QueuePayload, queue?: string, delaySeconds?: number): Promise<string>;
841
+ pop(_queue?: string): Promise<QueueJob | undefined>;
842
+ /** Jobs on `queue` (every queue when omitted), whatever connection they were pushed on, like Laravel's fake. */
843
+ size(queue?: string): Promise<number>;
844
+ /** Removes the jobs size() counts and returns how many. */
845
+ clear(queue?: string): Promise<number>;
846
+ extend(_driver: string, _factory: (config: Record<string, unknown>) => Queue): void;
847
+ /** Pushed at least once; a number asserts the count; a filter gets (job, queue, connection). */
848
+ assertPushed<J extends Job>(job: Target<J>, callback?: CountOrFilter<[J, string | undefined, string | undefined]>): void;
849
+ assertPushedTimes<J extends Job>(job: Target<J>, times?: number): void;
850
+ assertPushedOn<J extends Job>(queue: string, job: Target<J>, callback?: Filter$2<J>): void;
851
+ assertNotPushed<J extends Job>(job: Target<J>, callback?: Filter$2<J>): void;
852
+ assertNothingPushed(): void;
853
+ assertCount(expected: number): void;
854
+ /** The job was pushed with exactly this chain (Bus stores it on the first job under the protocol key). */
855
+ assertPushedWithChain<J extends Job>(job: Target<J>, expectedChain: Array<Target | Job>, callback?: Filter$2<J>): void;
856
+ assertPushedWithoutChain<J extends Job>(job: Target<J>, callback?: Filter$2<J>): void;
857
+ /** Pushed jobs matching the target (raw payloads match by their registry name or display name). */
858
+ pushed<J extends Job>(job: Target<J>, callback?: Filter$2<J>): J[];
859
+ hasPushed<J extends Job>(job: Target<J>): boolean;
860
+ private record;
861
+ private recordRaw;
862
+ /** The job is on `queue` (any when undefined) and, when `connection` is given, was pushed on that connection name. */
863
+ private on;
864
+ private remove;
865
+ private targets;
866
+ private nameOf;
867
+ private shouldFake;
868
+ private real;
869
+ }
870
+
871
+ /** A mailable the fake saw, with its resolved recipients (PendingMail's, else the envelope's) and subject. */
872
+ declare class MailRecord<M extends Mailable = Mailable> {
873
+ readonly mailable: M;
874
+ readonly mailer: string | undefined;
875
+ readonly to: Address[];
876
+ readonly cc: Address[];
877
+ readonly bcc: Address[];
878
+ readonly subject: string | undefined;
879
+ readonly queued: boolean;
880
+ readonly delay: number | undefined;
881
+ constructor(mailable: M, mailer: string | undefined, to: Address[], cc: Address[], bcc: Address[], subject: string | undefined, queued: boolean, delay: number | undefined);
882
+ hasTo(address: MailRecipient): boolean;
883
+ hasCc(address: MailRecipient): boolean;
884
+ hasBcc(address: MailRecipient): boolean;
885
+ hasSubject(subject: string): boolean;
886
+ }
887
+ type Filter$1<M extends Mailable> = (mailable: M, mail: MailRecord<M>) => boolean;
888
+ /**
889
+ * Laravel's Mail::fake(): records what would have been sent or queued. Queueable mailables (the Queue/Bus
890
+ * protocol's rule) sent with send() count as queued, like the real Mailer. Nothing is rendered or delivered.
891
+ */
892
+ declare class MailFake implements MailManager {
893
+ readonly manager: MailManager | undefined;
894
+ readonly records: MailRecord[];
895
+ constructor(manager?: MailManager | undefined);
896
+ static fake(): MailFake;
897
+ mailer(name?: string): Mailer;
898
+ to(recipients: MailRecipient | MailRecipient[]): PendingMail;
899
+ send(mailable: Mailable): Promise<SentMessage | undefined>;
900
+ /** Recorded as sent, never queued, like the real sendNow(). */
901
+ sendNow(mailable: Mailable): Promise<SentMessage | undefined>;
902
+ queue(mailable: Mailable): Promise<void>;
903
+ extend(_transport: string, _factory: (config: Record<string, unknown>) => MailTransport): void;
904
+ /** Sent (not queued) at least once; a number asserts the count; a filter gets (mailable, record). */
905
+ assertSent<M extends Mailable>(mailable: Target<M>, callback?: CountOrFilter<[M, MailRecord<M>]>): void;
906
+ assertSentTimes<M extends Mailable>(mailable: Target<M>, times?: number): void;
907
+ assertNotSent<M extends Mailable>(mailable: Target<M>, callback?: Filter$1<M>): void;
908
+ assertNothingSent(): void;
909
+ assertSentCount(count: number): void;
910
+ assertQueued<M extends Mailable>(mailable: Target<M>, callback?: CountOrFilter<[M, MailRecord<M>]>): void;
911
+ assertNotQueued<M extends Mailable>(mailable: Target<M>, callback?: Filter$1<M>): void;
912
+ assertNothingQueued(): void;
913
+ assertQueuedCount(count: number): void;
914
+ /** Sent or queued. */
915
+ assertOutgoingCount(count: number): void;
916
+ assertNothingOutgoing(): void;
917
+ sent<M extends Mailable>(mailable: Target<M>, callback?: Filter$1<M>): M[];
918
+ queued<M extends Mailable>(mailable: Target<M>, callback?: Filter$1<M>): M[];
919
+ hasSent(mailable: Target<Mailable>): boolean;
920
+ hasQueued(mailable: Target<Mailable>): boolean;
921
+ private pending;
922
+ private sendVia;
923
+ private sendNowVia;
924
+ private queueVia;
925
+ private record;
926
+ private matching;
927
+ }
928
+ /** MailRecipient(s) → Address[] (strings, Address objects, or anything with email + name, such as a User model). */
929
+ declare function addresses(recipients: MailRecipient | MailRecipient[]): Address[];
930
+
931
+ /** One delivery the fake recorded: to whom, what, and on which channels (the notification's via()). */
932
+ interface SentNotification {
933
+ notifiable: Notifiable;
934
+ notification: Notification;
935
+ channels: string[];
936
+ }
937
+ type Filter<N extends Notification> = (notification: N, channels: string[], notifiable: Notifiable) => boolean;
938
+ /** Notification.route('mail', 'a@b.c'): an on-demand notifiable (Laravel's AnonymousNotifiable). */
939
+ declare class AnonymousNotifiable implements Notifiable {
940
+ private readonly dispatcher;
941
+ readonly routes: Map<string, unknown>;
942
+ constructor(dispatcher: NotificationDispatcher);
943
+ route(channel: string, route: unknown): this;
944
+ routeNotificationFor(channel: string): unknown;
945
+ notify(notification: Notification): Promise<void>;
946
+ }
947
+ /**
948
+ * Laravel's Notification::fake(): records notifications (send, sendNow, on-demand routes) instead of
949
+ * delivering or queueing them. The Notifiable mixin's notify() resolves the dispatcher per call, so it lands here.
950
+ */
951
+ declare class NotificationFake implements NotificationDispatcher {
952
+ readonly dispatcher: NotificationDispatcher | undefined;
953
+ readonly notifications: SentNotification[];
954
+ constructor(dispatcher?: NotificationDispatcher | undefined);
955
+ static fake(): NotificationFake;
956
+ send(notifiables: Notifiable | Iterable<Notifiable>, notification: Notification): Promise<void>;
957
+ sendNow(notifiables: Notifiable | Iterable<Notifiable>, notification: Notification, channels?: string[]): Promise<void>;
958
+ route(channel: string, route: unknown): AnonymousNotifiable;
959
+ /** The Notifications provider calls this in boot(); a fake has no channels to register. */
960
+ extend(_channel: string, _factory: () => NotificationChannel): void;
961
+ /** Sent to the notifiable(s); a number asserts the count; a filter gets (notification, channels, notifiable). */
962
+ assertSentTo<N extends Notification>(notifiable: Notifiable | Iterable<Notifiable>, notification: Target<N>, callback?: CountOrFilter<[N, string[], Notifiable]>): void;
963
+ assertSentToTimes<N extends Notification>(notifiable: Notifiable, notification: Target<N>, times?: number): void;
964
+ assertNotSentTo<N extends Notification>(notifiable: Notifiable | Iterable<Notifiable>, notification: Target<N>, callback?: Filter<N>): void;
965
+ /** Sent through Notification.route(...) (an anonymous notifiable). */
966
+ assertSentOnDemand<N extends Notification>(notification: Target<N>, callback?: CountOrFilter<[N, string[], AnonymousNotifiable]>): void;
967
+ assertNothingSent(): void;
968
+ assertNothingSentTo(notifiable: Notifiable): void;
969
+ /** Sent this many times in total, to anyone. */
970
+ assertSentTimes(notification: Target<Notification>, times: number): void;
971
+ assertCount(expected: number): void;
972
+ sent<N extends Notification>(notifiable: Notifiable, notification: Target<N> | Class<N>, callback?: Filter<N>): N[];
973
+ hasSent(notifiable: Notifiable, notification: Target<Notification>): boolean;
974
+ private record;
975
+ }
976
+
977
+ interface StoredFile {
978
+ bytes: Uint8Array;
979
+ visibility: 'public' | 'private';
980
+ mimeType: string | undefined;
981
+ modified: Date;
982
+ }
983
+ /** By the extension as PHP's pathinfo() reads it: after the last dot of the base name ('.pdf' is a PDF, 'pdf' isn't). */
984
+ declare function guessMimeType(path: string): string | undefined;
985
+ /**
986
+ * An in-memory disk implementing the Filesystem contract, with Laravel's fake-disk assertions. (Laravel's fake
987
+ * writes to storage/framework/testing/disks; this one keeps files in memory, so there's nothing to clean up.)
988
+ */
989
+ declare class FakeDisk implements Filesystem {
990
+ readonly name: string;
991
+ private readonly urlPrefix;
992
+ /** Stored files by normalized path. */
993
+ readonly stored: Map<string, StoredFile>;
994
+ /** Directories made explicitly (others exist because files are in them). */
995
+ readonly made: Set<string>;
996
+ constructor(name: string, urlPrefix?: string);
997
+ exists(path: string): Promise<boolean>;
998
+ missing(path: string): Promise<boolean>;
999
+ get(path: string): Promise<string>;
1000
+ getBytes(path: string): Promise<Uint8Array>;
1001
+ readStream(path: string): Promise<ReadableStream<Uint8Array>>;
1002
+ put(path: string, contents: string | Uint8Array | ReadableStream<Uint8Array>, options?: PutOptions): Promise<boolean>;
1003
+ putFile(directory: string, file: UploadedFile, options?: PutOptions): Promise<string>;
1004
+ /**
1005
+ * The upload's own type, as the S3 disk sends it: its extension(), never the MIME type the client sent as such nor
1006
+ * the stored name's type.
1007
+ */
1008
+ putFileAs(directory: string, file: UploadedFile, name: string, options?: PutOptions): Promise<string>;
1009
+ private write;
1010
+ delete(paths: string | string[]): Promise<boolean>;
1011
+ copy(from: string, to: string): Promise<boolean>;
1012
+ move(from: string, to: string): Promise<boolean>;
1013
+ size(path: string): Promise<number>;
1014
+ lastModified(path: string): Promise<Date>;
1015
+ mimeType(path: string): Promise<string | undefined>;
1016
+ url(path: string): string;
1017
+ temporaryUrl(path: string, expiresAt: Date): Promise<string>;
1018
+ files(directory?: string, recursive?: boolean): Promise<string[]>;
1019
+ directories(directory?: string, recursive?: boolean): Promise<string[]>;
1020
+ makeDirectory(path: string): Promise<boolean>;
1021
+ deleteDirectory(path: string): Promise<boolean>;
1022
+ /** A virtual absolute path (the files only exist in memory). */
1023
+ path(path: string): string;
1024
+ /** The file(s) exist; with `content`, the (single) file has exactly that content. */
1025
+ assertExists(path: string | string[], content?: string): Promise<this>;
1026
+ assertMissing(path: string | string[]): Promise<this>;
1027
+ assertDirectoryEmpty(path: string): Promise<this>;
1028
+ assertCount(path: string, count: number, recursive?: boolean): Promise<this>;
1029
+ private read;
1030
+ private isDirectory;
1031
+ }
1032
+ /**
1033
+ * Laravel's Storage::fake('avatars'): swaps the FilesystemManager for one whose faked disks live in memory
1034
+ * (other disks still reach the real manager). Returns the fake disk.
1035
+ */
1036
+ declare class StorageFake implements FilesystemManager {
1037
+ readonly manager: FilesystemManager | undefined;
1038
+ private readonly defaultDisk;
1039
+ readonly disks: Map<string, FakeDisk>;
1040
+ constructor(manager: FilesystemManager | undefined, defaultDisk: string);
1041
+ static fake(disk?: string): FakeDisk;
1042
+ disk(name?: string): Filesystem;
1043
+ extend(driver: string, factory: (config: Record<string, unknown>) => Filesystem): void;
1044
+ exists(path: string): Promise<boolean>;
1045
+ missing(path: string): Promise<boolean>;
1046
+ get(path: string): Promise<string>;
1047
+ getBytes(path: string): Promise<Uint8Array<ArrayBufferLike>>;
1048
+ readStream(path: string): Promise<ReadableStream<Uint8Array<ArrayBufferLike>>>;
1049
+ put(path: string, contents: string | Uint8Array | ReadableStream<Uint8Array>, options?: PutOptions): Promise<boolean>;
1050
+ putFile(directory: string, file: UploadedFile, options?: PutOptions): Promise<string>;
1051
+ putFileAs(directory: string, file: UploadedFile, name: string, options?: PutOptions): Promise<string>;
1052
+ delete(paths: string | string[]): Promise<boolean>;
1053
+ copy(from: string, to: string): Promise<boolean>;
1054
+ move(from: string, to: string): Promise<boolean>;
1055
+ size(path: string): Promise<number>;
1056
+ lastModified(path: string): Promise<Date>;
1057
+ mimeType(path: string): Promise<string | undefined>;
1058
+ url(path: string): string;
1059
+ temporaryUrl(path: string, expiresAt: Date): Promise<string>;
1060
+ files(directory?: string, recursive?: boolean): Promise<string[]>;
1061
+ directories(directory?: string, recursive?: boolean): Promise<string[]>;
1062
+ makeDirectory(path: string): Promise<boolean>;
1063
+ deleteDirectory(path: string): Promise<boolean>;
1064
+ path(path: string): string;
1065
+ }
1066
+
1067
+ /** Laravel's UploadedFile::fake(): File objects to post as multipart uploads (t.post(uri, { avatar: file })). */
1068
+ declare const FakeFile: {
1069
+ /**
1070
+ * A file of `kilobytes` KiB typed by `mimeType` or the name's extension. Validation reads a file's bytes, so the
1071
+ * file starts like its type (a PDF's `%PDF-`, a PNG's signature, text for text types) and passes `mimes` for its
1072
+ * name, as Laravel's fakes do. It is at least its type's leading bytes and never empty, whatever the size asked for.
1073
+ * An image made this way has no readable size: use image() for `dimensions`.
1074
+ */
1075
+ create(name: string, kilobytes?: number, mimeType?: string): File;
1076
+ /**
1077
+ * A real white image of the given size in the format the name's extension asks for: png, jpg/jpeg, gif, webp or
1078
+ * bmp (any other name gets a JPEG, as Laravel's fakes do), so image, mimes and dimensions pass on it.
1079
+ */
1080
+ image(name: string, width?: number, height?: number): File;
1081
+ };
1082
+
1083
+ /** Marks Live component classes (Symbol.for, so two copies of the package agree). */
1084
+ declare const COMPONENT: unique symbol;
1085
+ /** A browser event queued by dispatch(). `to` is resolved to a component name when the effects are built. */
1086
+ interface QueuedDispatch {
1087
+ name: string;
1088
+ params: Record<string, unknown>;
1089
+ self?: true;
1090
+ to?: string | Class<Component>;
1091
+ }
1092
+ /** The validation errors of a component (Laravel's MessageBag), for render(): `this.errors.first('title')`. */
1093
+ declare class ErrorBag implements MessageBag {
1094
+ #private;
1095
+ private readonly messages;
1096
+ constructor(messages: Record<string, string[]>);
1097
+ /** Adds to the component's errors, as addError() does. */
1098
+ add(key: string, message: string): void;
1099
+ has(key: string): boolean;
1100
+ first(key?: string): string | undefined;
1101
+ get(key: string): string[];
1102
+ all(): string[];
1103
+ any(): boolean;
1104
+ isEmpty(): boolean;
1105
+ count(): number;
1106
+ toObject(): Record<string, string[]>;
1107
+ }
1108
+ /** What dispatch() returns: `this.dispatch('saved').self()` or `.to(Sidebar)`. */
1109
+ declare class PendingEvent {
1110
+ private readonly event;
1111
+ constructor(event: QueuedDispatch);
1112
+ /** Only this component's own listeners receive the event. */
1113
+ self(): this;
1114
+ /** Only components of this class (or registered name) receive the event. */
1115
+ to(component: string | Class<Component>): this;
1116
+ }
1117
+ /**
1118
+ * A Live component (Livewire 3): public fields are its state, public methods are actions the browser can call, and
1119
+ * render() returns its TSX. Lifecycle hooks, all optional: `boot()`, `mount(params)`, `hydrate()`, `dehydrate()`,
1120
+ * `updating(name, value)`/`updated(name, value)` and per property `updatingTitle(value)`/`updatedTitle(value)`,
1121
+ * `rendering()`/`rendered(html)`. Fields that must not be state use `#private` syntax.
1122
+ */
1123
+ declare abstract class Component {
1124
+ static readonly [COMPONENT] = true;
1125
+ /** The view that wraps a full-page component (default: config `live.layout`). */
1126
+ static layout?: string;
1127
+ /** The page title passed to the layout as `title`. */
1128
+ static title?: string;
1129
+ /**
1130
+ * Livewire's #[Lazy]: every embed (and the full page) renders the placeholder first and mounts once the browser shows
1131
+ * it. `<Live component={…} lazy={false} />` mounts one at once. The placeholder is the component's
1132
+ * `placeholder(params)` method (TSX), else the `live.lazy_placeholder` view, else an empty `<div>`: give it the root
1133
+ * element the component renders.
1134
+ */
1135
+ static lazy?: boolean;
1136
+ /** Static fallbacks for runtimes without decorators: { event: 'method' }, locked names, computed getter names. */
1137
+ static listeners?: Record<string, string>;
1138
+ static locked?: string[];
1139
+ static computed?: string[];
1140
+ abstract render(): unknown;
1141
+ getId(): string;
1142
+ getName(): string;
1143
+ /** Dispatches a browser event; every component listening for it (@On) runs its handler. */
1144
+ dispatch(name: string, params?: Record<string, unknown>): PendingEvent;
1145
+ /** Sends the browser to `url` after this request; `navigate` uses o:navigate instead of a full page load. */
1146
+ redirect(url: string, options?: {
1147
+ navigate?: boolean;
1148
+ }): void;
1149
+ /**
1150
+ * redirect() to a named route: `this.redirectRoute('posts.show', post, { navigate: true })`. Once `oriel
1151
+ * route:types` has run, the name and the route's parameters are checked, as route()'s are.
1152
+ */
1153
+ redirectRoute<N extends RouteName>(name: N, ...args: RouteArguments<N, [options?: {
1154
+ navigate?: boolean;
1155
+ }]>): void;
1156
+ /**
1157
+ * Validates the public state. On success clears the error bag and returns the validated data, typed from the rules
1158
+ * (`await this.validate({ title: 'required|string' })` is `{ title: string }`); on failure fills the error bag and
1159
+ * throws (the rest of the action is skipped and the component re-renders with `errors`).
1160
+ */
1161
+ validate<const R extends Rules>(rules: R, messages?: Record<string, string>, attributes?: Record<string, string>): Promise<InferValidatedType<R>>;
1162
+ addError(key: string, message: string): void;
1163
+ /** Clears every error, or only those of `keys`. */
1164
+ resetErrorBag(...keys: string[]): void;
1165
+ get errors(): ErrorBag;
1166
+ /** Puts public properties (all of them when none are named) back to their initial values. */
1167
+ reset(...properties: string[]): void;
1168
+ /** Keeps the current HTML: the response carries the new state but no `html` effect. */
1169
+ skipRender(): void;
1170
+ /**
1171
+ * An action for an `o:` directive, typed against its method: `o:click={this.$action(this.delete, tag.id)}` writes
1172
+ * `delete(5)`, and a string where `delete` takes a number is a type error. The arguments are written as JSON, the
1173
+ * trailing `undefined` ones left out so the method's defaults apply. The method must be one of this component's
1174
+ * actions (a public method of its class, not a hook and not @Locked); anything else throws while rendering.
1175
+ */
1176
+ $action<P extends unknown[]>(method: (...params: P) => unknown, ...params: NoInfer<P>): string;
1177
+ /** A full-page component as a route action: Route.get('/counter', Counter). Route parameters go to mount(). */
1178
+ __invoke(): Promise<unknown>;
1179
+ }
1180
+
1181
+ /** @On('post-created'): calls the method when the event is dispatched (by this or any component, or the browser). */
1182
+ declare function On(event: string): (_method: unknown, context: ClassMethodDecoratorContext) => void;
1183
+ /** @Locked: a property the browser can't change, or a method the browser can't call. */
1184
+ declare function Locked(_target: unknown, context: ClassFieldDecoratorContext | ClassMethodDecoratorContext): void;
1185
+ /** @Computed: a getter cached for the rest of the request, never part of the component's state. */
1186
+ declare function Computed<T>(getter: (this: object) => T, context: ClassGetterDecoratorContext): (this: object) => T;
1187
+
1188
+ /**
1189
+ * Runs Live.test()'s mount and each update. The testing package binds one for every test, so they run in a request
1190
+ * scope like the test's HTTP requests (a request, the carried session, actingAs users) and what they change carries
1191
+ * on to the next request. Without one they run in the current scope.
1192
+ */
1193
+ type TestRequestScope = <T>(run: () => Promise<T>) => Promise<T>;
1194
+ declare const TestRequestScope: Token<TestRequestScope>;
1195
+ /**
1196
+ * Livewire's Livewire::test(): drives one component through the real mount → snapshot → checksum → update pipeline
1197
+ * (no HTTP), inside the test's request scope. Actions are async (`await counter.call('increment')`); assertions are
1198
+ * sync and return `this`.
1199
+ */
1200
+ declare class Testable<C extends Component = Component> {
1201
+ #private;
1202
+ private readonly manager;
1203
+ private readonly scope;
1204
+ private constructor();
1205
+ /**
1206
+ * Mounts `component` with `params`, as `<Live component={…} {...params} />` would. A lazy component mounts at once
1207
+ * (Livewire's withoutLazyLoading()); `{ lazy: true }` renders its placeholder, and `call('__lazyLoad', …)` loads it.
1208
+ */
1209
+ static create<C extends Component>(component: Class<C> | string, params?: Record<string, unknown>): Promise<Testable<C>>;
1210
+ /** The component instance after the last request. */
1211
+ instance(): C;
1212
+ /** A public property (dotted paths reach into arrays and objects). */
1213
+ get<T = unknown>(path: string): T;
1214
+ /** The last rendered HTML, without the o:id, o:snapshot and o:effects attributes (Livewire strips them too). */
1215
+ html(): string;
1216
+ /** The effects of the last request. */
1217
+ effects(): LiveEffects;
1218
+ /**
1219
+ * Sets public properties through an update. A file (a FakeFile) or an array of files is uploaded as `o:model` on a
1220
+ * file input does it: the upload rules, the temporary disk, then a TemporaryUploadedFile (or an array) in the
1221
+ * property, or the upload's errors on it (Livewire's).
1222
+ */
1223
+ set(path: string | Record<string, unknown>, value?: unknown): Promise<this>;
1224
+ /** Uploads `files` into the property `name` (an array when `multiple`), as the browser's upload calls do. */
1225
+ upload(name: string, files: readonly Blob[], multiple?: boolean): Promise<this>;
1226
+ call(method: string, ...params: unknown[]): Promise<this>;
1227
+ toggle(path: string): Promise<this>;
1228
+ /** Dispatches an event to this component, as the browser does for its listeners. */
1229
+ dispatch(event: string, params?: Record<string, unknown>): Promise<this>;
1230
+ refresh(): Promise<this>;
1231
+ assertSet(path: string, value: unknown): this;
1232
+ assertNotSet(path: string, value: unknown): this;
1233
+ /** Each value, HTML-escaped, appears in the rendered HTML. */
1234
+ assertSee(...values: string[]): this;
1235
+ assertDontSee(...values: string[]): this;
1236
+ /** Each value appears in the rendered HTML as written (not escaped). */
1237
+ assertSeeHtml(...values: string[]): this;
1238
+ /** Each value, HTML-escaped, appears in the rendered text: the HTML with its tags stripped (Livewire's assertSeeText). */
1239
+ assertSeeText(...values: string[]): this;
1240
+ assertDontSeeText(...values: string[]): this;
1241
+ assertDispatched(name: string, params?: Record<string, unknown>): this;
1242
+ assertNotDispatched(name: string): this;
1243
+ /** The error bag has errors for every key given (or any error at all with no keys). */
1244
+ assertHasErrors(keys?: string | string[]): this;
1245
+ /** No errors for the keys given (or none at all with no keys). */
1246
+ assertHasNoErrors(keys?: string | string[]): this;
1247
+ assertRedirect(url?: string): this;
1248
+ assertNoRedirect(): this;
1249
+ /** The last call returned `value`. */
1250
+ assertReturned(value: unknown): this;
1251
+ }
1252
+
1253
+ /** Props of `<Live component={Counter} count={3} o:key="c1" />`: the rest become mount params. */
1254
+ interface LiveProps {
1255
+ component: Class<Component> | string;
1256
+ /** Identifies a child inside its parent across re-renders (Livewire's :key / wire:key). */
1257
+ 'o:key'?: string | number;
1258
+ /**
1259
+ * Renders the placeholder and mounts the component once it scrolls into view (`'on-load'`: once the page starts);
1260
+ * `false` mounts a `static lazy` component at once.
1261
+ */
1262
+ lazy?: boolean | 'on-load';
1263
+ [param: string]: unknown;
1264
+ }
1265
+ /** Blade's @livewire('counter', ['count' => 3], key('c1')): the component's first render, as trusted HTML. */
1266
+ declare function live(component: Class<Component> | string, params?: Record<string, unknown>, key?: string | number): Promise<Htmlable>;
1267
+ /** `<Live component={Counter} />` in any view or component. */
1268
+ declare function LiveComponent({ component, 'o:key': key, children: _children, ...params }: LiveProps): Promise<Htmlable>;
1269
+ /** The `<Live />` element, and the Live facade: Live.component(name, Class), Live.test(Component). */
1270
+ declare const Live: typeof LiveComponent & {
1271
+ /** Registers a component under a name (components in app/Live are registered at boot). */
1272
+ component(name: string, component: Class<Component>): void;
1273
+ /** Livewire::test(): mounts `component` for assertions. */
1274
+ test<C extends Component>(component: Class<C> | string, params?: Record<string, unknown>): Promise<Testable<C>>;
1275
+ };
1276
+
1277
+ type Call = {
1278
+ method: string;
1279
+ params: unknown[];
1280
+ };
1281
+ /** One component after a mount or an update: the live instance (for Live.test), its snapshot, effects and HTML. */
1282
+ interface ComponentResult {
1283
+ instance: Component;
1284
+ snapshot: LiveSnapshot;
1285
+ effects: LiveEffects;
1286
+ /** The rendered HTML with o:id (and, after a mount, o:snapshot/o:effects); undefined after skipRender(). */
1287
+ html?: string;
1288
+ tag?: string;
1289
+ }
1290
+ /** Livewire's update request handling and first render, on Oriel's contracts. */
1291
+ declare class LiveComponentManager implements LiveManager {
1292
+ private readonly app;
1293
+ constructor(app: Application);
1294
+ /** The request scope when there is one (sessions, the current route), else the application. */
1295
+ private container;
1296
+ private registry;
1297
+ /** Live.component('counter', Counter): registers a component under a name the snapshots use. */
1298
+ register(component: Class<unknown>, name?: string): void;
1299
+ /** The registered name of a component class, registering it under its kebab-case class name the first time. */
1300
+ nameOf(component: Class<Component>): string;
1301
+ resolve(name: string): Class<Component>;
1302
+ isLiveRequest(request: HttpRequest): boolean;
1303
+ /** The first render: HTML with o:id, o:snapshot and o:effects on the root element. */
1304
+ mount(component: string | Class<unknown>, params?: Record<string, unknown>, key?: string): Promise<string>;
1305
+ /**
1306
+ * Mounts a component: boot(), the params into its properties, mount(params), then its first render. A lazy one
1307
+ * (`lazy` in the params, or `static lazy`) renders its placeholder instead and mounts when the browser loads it.
1308
+ */
1309
+ mountComponent(component: string | Class<unknown>, embedParams?: Record<string, unknown>, existing?: Component): Promise<ComponentResult>;
1310
+ /**
1311
+ * A lazy component's first render (Livewire's): its placeholder, with the state it has before mount() and the mount
1312
+ * params signed for the `__lazyLoad` call the browser makes when it shows it (`o:lazy`, or `o:lazy-on-load`).
1313
+ */
1314
+ private mountPlaceholder;
1315
+ /** Applies each component's updates and calls, re-renders it and returns its new snapshot and effects. */
1316
+ update(request: LiveUpdateRequest): Promise<LiveUpdateResponse>;
1317
+ updateComponent(snapshotJson: string, updates: Record<string, unknown>, calls: Call[]): Promise<ComponentResult>;
1318
+ /**
1319
+ * The mount params and placeholder tag of a `__lazyLoad` request, or undefined for any other update. The load comes
1320
+ * alone (no updates, no other call: the browser sends it in a request of its own) and its payload must be the one
1321
+ * signed for this component: anything else is refused as corrupt (a 403) before the component boots.
1322
+ */
1323
+ private lazyLoad;
1324
+ /**
1325
+ * The route action of POST /oriel/live/update. Each component's update runs behind the persistent middleware of the
1326
+ * route that rendered its page (Livewire's): `auth`, `verified`, `guest` and `can`, with the page route's parameters
1327
+ * bound again. A signed-out tab gets a 401, a revoked ability a 403 and a deleted model a 404, before the component
1328
+ * hydrates. When a middleware answers instead (a redirect), that is the response. A key first flashed during the
1329
+ * update shows in this response only, unless the update redirects.
1330
+ */
1331
+ handle(request: HttpRequest): Promise<LiveUpdateResponse | Response>;
1332
+ /** A full-page component (Route.get('/counter', Counter)): mounted with the route parameters, inside the layout. */
1333
+ page(component: Component): Promise<unknown>;
1334
+ /** Parses and checks a snapshot: a bad checksum throws before anything is hydrated. */
1335
+ private verify;
1336
+ private key;
1337
+ /** The request body, read from the raw JSON when the request has it, so TrimStrings can't alter typed values. */
1338
+ private payload;
1339
+ /** Makes every computed getter (static `computed` too) cache its value for the rest of the request. */
1340
+ private prepareComputed;
1341
+ private applyUpdate;
1342
+ /** Runs one call from the browser: a magic action, an event, an upload call, or a public method. Returns its return value. */
1343
+ private call;
1344
+ /**
1345
+ * Renders the component (rendering/rendered hooks, nested children tracked) and checks for a single root. A
1346
+ * WithPagination component's page and page URL are what paginate() reads while it renders, as in its mount() and in
1347
+ * its update's hooks and actions.
1348
+ */
1349
+ private render;
1350
+ /** The absolute URL of the page a memo path belongs to, on the current request's origin ('/' + path without one). */
1351
+ private pageUrl;
1352
+ /** Dispatches, redirects: the effects every response carries. */
1353
+ private effects;
1354
+ /** dehydrate() hook, then the state as snapshot data, the error bag, and the checksum over both. */
1355
+ private snapshot;
1356
+ }
1357
+
1358
+ /** The URI the client runtime posts updates to. */
1359
+ declare const UPDATE_URI = "/oriel/live/update";
1360
+ /**
1361
+ * Binds the LiveManager and the PaginationState that WithPagination components answer, merges the `live` config,
1362
+ * registers POST /oriel/live/update (named `live.update`, in the `web` group: sessions and CSRF apply), the upload and
1363
+ * preview routes of WithFileUploads (`live.upload-file`, `live.preview-file`), the make:live command, and the
1364
+ * components under app/Live.
1365
+ */
1366
+ declare class LiveServiceProvider extends ServiceProvider$1 {
1367
+ register(): void;
1368
+ boot(): Promise<void>;
1369
+ }
1370
+
1371
+ /** A component's Livewire name from its path under app/Live: Posts/CreatePost.tsx → posts.create-post. */
1372
+ declare function componentName(file: string): string;
1373
+
1374
+ /** A Live programming error (unsupported state, a missing root element, an unknown component): a 500. */
1375
+ declare class LiveError extends Error implements OrielError {
1376
+ readonly name: string;
1377
+ readonly kind: ErrorKind;
1378
+ readonly status: number;
1379
+ }
1380
+ /** A snapshot whose checksum doesn't match (tampered with, or signed with another APP_KEY). Nothing is hydrated. */
1381
+ declare class CorruptComponentPayloadError extends LiveError {
1382
+ readonly name: string;
1383
+ readonly kind: ErrorKind;
1384
+ readonly status: number;
1385
+ constructor(component?: string);
1386
+ }
1387
+ /** The browser asked for a method that isn't a public action of the component. */
1388
+ declare class MethodNotCallableError extends LiveError {
1389
+ readonly name: string;
1390
+ readonly kind: ErrorKind;
1391
+ readonly status: number;
1392
+ constructor(method: string, component: string);
1393
+ }
1394
+ /** The browser tried to set a property that is locked, computed, private (`_x`) or not declared. */
1395
+ declare class PropertyNotUpdatableError extends LiveError {
1396
+ readonly name: string;
1397
+ readonly kind: ErrorKind;
1398
+ readonly status: number;
1399
+ constructor(path: string, component: string);
1400
+ }
1401
+ /** A snapshot names a component that isn't registered. */
1402
+ declare class LiveComponentNotFoundError extends LiveError {
1403
+ readonly name: string;
1404
+ readonly kind: ErrorKind;
1405
+ readonly status: number;
1406
+ constructor(component: string);
1407
+ }
1408
+ /** An update request without the X-Oriel-Live header or with a malformed body. */
1409
+ declare class InvalidLiveRequestError extends LiveError {
1410
+ readonly name: string;
1411
+ readonly kind: ErrorKind;
1412
+ readonly status: number;
1413
+ }
1414
+ /** An upload or preview URL whose signature is missing, wrong or expired (Livewire's 401). Nothing is read or stored. */
1415
+ declare class InvalidUploadSignatureError extends LiveError {
1416
+ readonly name: string;
1417
+ readonly kind: ErrorKind;
1418
+ readonly status: number;
1419
+ constructor();
1420
+ }
1421
+ /** A preview of a temporary upload that is no longer on the disk (cleaned up, or stored and deleted). */
1422
+ declare class TemporaryFileNotFoundError extends LiveError {
1423
+ readonly name: string;
1424
+ readonly kind: ErrorKind;
1425
+ readonly status: number;
1426
+ constructor(filename: string);
1427
+ }
1428
+ /** temporaryUrl() on an upload whose type has no preview (live.temporary_file_upload.preview_mimes). */
1429
+ declare class FileNotPreviewableError extends LiveError {
1430
+ readonly name: string;
1431
+ constructor(extension: string);
1432
+ }
1433
+ /** The errors an upload came back with (`_uploadErrored`): the component re-renders with them on the property. */
1434
+ declare class UploadValidationError extends LiveError {
1435
+ readonly errors: Record<string, string[]>;
1436
+ readonly name: string;
1437
+ readonly kind: ErrorKind;
1438
+ readonly status: number;
1439
+ readonly errorBag: string;
1440
+ constructor(errors: Record<string, string[]>);
1441
+ }
1442
+
1443
+ /**
1444
+ * Livewire's `temporary_file_upload` settings, read from config `live.temporary_file_upload.*` (each one falls back on
1445
+ * its own): the disk (the default filesystem disk), the directory on it, the rules every upload must pass, the upload
1446
+ * route's middleware, the types a preview is served for, how long an upload URL lasts (minutes), and whether a finished
1447
+ * upload removes the temporary files older than a day.
1448
+ */
1449
+ declare const TEMPORARY_UPLOAD_DEFAULTS: {
1450
+ disk: string | null;
1451
+ directory: string;
1452
+ rules: string | string[];
1453
+ middleware: string | string[];
1454
+ preview_mimes: string[];
1455
+ max_upload_time: number;
1456
+ cleanup: boolean;
1457
+ };
1458
+ /** What a temporary upload is: its stored name on the temporary disk and what the browser sent (signed with it). */
1459
+ interface TemporaryFileData {
1460
+ /** A random 40-character name with the extension its bytes showed: `live-tmp/<filename>` on the temporary disk. */
1461
+ filename: string;
1462
+ /** The name the browser gave the file. */
1463
+ name: string;
1464
+ size: number;
1465
+ /** The MIME type the browser claimed. */
1466
+ type: string;
1467
+ /** The extension of the upload's own type (its bytes, else a plain claimed extension), or ''. */
1468
+ extension: string;
1469
+ }
1470
+ /**
1471
+ * Livewire's TemporaryUploadedFile: a file the browser uploaded to the temporary directory before an action stores
1472
+ * it. A WithFileUploads component's property holds one (or an array of them) once `o:model` on a file input has
1473
+ * uploaded it: validate it like any upload (`'photo' => 'image|max:1024'`), preview it with `temporaryUrl()`, then
1474
+ * `store()` it. It travels in the component's snapshot as its data, signed with the rest.
1475
+ */
1476
+ declare class TemporaryUploadedFile implements UploadedFile {
1477
+ #private;
1478
+ readonly filename: string;
1479
+ readonly clientName: string;
1480
+ readonly mimeType: string;
1481
+ readonly size: number;
1482
+ constructor(data: TemporaryFileData);
1483
+ /** What the snapshot carries. */
1484
+ toData(): TemporaryFileData;
1485
+ /** The file's path on the temporary disk. */
1486
+ get path(): string;
1487
+ /** The extension of the upload's own type, as FormUploadedFile's extension(): what putFile() names a stored copy by. */
1488
+ extension(): string;
1489
+ /** The extension of the name the browser gave the file, lower-cased ('' without one). */
1490
+ clientExtension(): string;
1491
+ /** A random 40-character name with extension(), as FormUploadedFile's. */
1492
+ hashName(): string;
1493
+ arrayBuffer(): Promise<ArrayBuffer>;
1494
+ text(): Promise<string>;
1495
+ /** The file's bytes from the temporary disk, opened on the first read. */
1496
+ stream(): ReadableStream<Uint8Array>;
1497
+ /** Stores a copy under a random name in `directory`, on `disk` (by default the temporary disk, as Livewire's). */
1498
+ store(directory: string, disk?: string): Promise<string>;
1499
+ storeAs(directory: string, name: string, disk?: string): Promise<string>;
1500
+ exists(): Promise<boolean>;
1501
+ /** Removes the temporary file (a stored copy stays). */
1502
+ delete(): Promise<boolean>;
1503
+ /** Whether temporaryUrl() serves this file: its type is in `live.temporary_file_upload.preview_mimes`. */
1504
+ isPreviewable(): boolean;
1505
+ /**
1506
+ * A signed link to the file for `<img src>` or `<video src>` before it is stored. It lasts until the end of the hour
1507
+ * at least 30 minutes away (Livewire's), so a re-render keeps the same link and the browser doesn't reload it.
1508
+ */
1509
+ temporaryUrl(): string;
1510
+ }
1511
+
1512
+ /** Where the browser POSTs a WithFileUploads component's files (Livewire's /livewire/upload-file), named live.upload-file. */
1513
+ declare const UPLOAD_URI = "/oriel/live/upload-file";
1514
+ /** Where temporaryUrl() links lead (Livewire's /livewire/preview-file/{filename}), named live.preview-file. */
1515
+ declare const PREVIEW_URI = "/oriel/live/preview-file";
1516
+
1517
+ /** The route middleware an update re-applies by default (config live.persistent_middleware), by alias. */
1518
+ declare const PERSISTENT_MIDDLEWARE: string[];
1519
+ /** A route middleware after alias and group expansion: 'auth:web' → { cls: Authenticate, parameters: ['web'] }. */
1520
+ interface PersistentMiddleware {
1521
+ readonly cls: MiddlewareClass;
1522
+ readonly parameters: readonly string[];
1523
+ }
1524
+ /**
1525
+ * Livewire's persistent middleware: the middleware among `persistent` (aliases) that the page route (the component's
1526
+ * memo path and method) ran, in the order an update runs them. A path no route matches has none.
1527
+ */
1528
+ declare function persistentMiddleware(router: Router, persistent: readonly string[], method: string, path: string): PersistentMiddleware[];
1529
+
1530
+ type ComponentConstructor = abstract new (...args: any[]) => Component;
1531
+ /** What WithPagination() adds to a component: its page and the actions that move it. */
1532
+ interface Paginated {
1533
+ /** The current page. The browser may set it; Live reads it as a page number. */
1534
+ page: number;
1535
+ nextPage(): Promise<void>;
1536
+ previousPage(): Promise<void>;
1537
+ gotoPage(page: number | string): Promise<void>;
1538
+ resetPage(): Promise<void>;
1539
+ setPage(page: number | string): Promise<void>;
1540
+ }
1541
+ /**
1542
+ * Livewire's WithPagination: `class Posts extends WithPagination(Component)`. The public `page` (1 to start; there
1543
+ * is no address-bar sync) is what `paginate()` shows in the component (in `render()`, `mount()`, `hydrate()`, the
1544
+ * update hooks and actions, or in a `@Computed` getter any of them reads), and its page links are built on the
1545
+ * page's URL. The actions move it: `o:click="nextPage"`, `previousPage`, `gotoPage(3)`, `setPage(3)`,
1546
+ * `resetPage` (call it from `updatedSearch()` so a new search starts on page 1). `updatingPage(page)` and
1547
+ * `updatedPage(page)` run around every change. One paginator per component: other page names read the request.
1548
+ */
1549
+ declare function WithPagination<TBase extends ComponentConstructor>(Base: TBase): TBase & (abstract new (...args: any[]) => Paginated);
1550
+
1551
+ /**
1552
+ * Livewire's WithFileUploads: `class Profile extends WithFileUploads(Component)`. A file input with `o:model="photo"`
1553
+ * uploads the file to the temporary directory as soon as it is picked, then sets `photo` to a TemporaryUploadedFile
1554
+ * (`<input type="file" multiple>` sets an array), through `updatingPhoto()`/`updatedPhoto()` like any update. Validate
1555
+ * it with the file rules, preview it with `temporaryUrl()`, store it with `store()`.
1556
+ */
1557
+ declare function WithFileUploads<TBase extends ComponentConstructor>(Base: TBase): TBase;
1558
+
1559
+ /**
1560
+ * What <Pagination> reads from a paginator. Structural, since Live can't import Database: paginate()'s
1561
+ * LengthAwarePaginator (with lastPage(), so page buttons) and simplePaginate()'s Paginator (Previous and Next only).
1562
+ */
1563
+ interface PaginationSource {
1564
+ currentPage(): number;
1565
+ lastPage?(): number;
1566
+ hasMorePages(): boolean;
1567
+ onFirstPage(): boolean;
1568
+ /** Page buttons on each side of the current one (the paginator's onEachSide(), 3 by default). */
1569
+ readonly onEachSideCount?: number;
1570
+ /** Not cursorPaginate(): its pages are cursors, which a component's page number can't follow. */
1571
+ readonly nextCursor?: never;
1572
+ }
1573
+ interface PaginationProps {
1574
+ paginator: PaginationSource;
1575
+ /** Classes for the <nav>, such as its layout ("flex gap-2"); in your file, so Tailwind generates them. */
1576
+ class?: string;
1577
+ }
1578
+ /**
1579
+ * Livewire's pagination links for a WithPagination component: `<Pagination paginator={posts} />` in render(). A
1580
+ * <nav aria-label="Pagination"> with « Previous, the page buttons and Next » as Live actions (previousPage,
1581
+ * gotoPage(n), nextPage), the current page marked aria-current="page", the ends disabled, the kits' theme classes
1582
+ * (btn, btn-secondary). Nothing when everything fits on one page. The address bar is left alone.
1583
+ */
1584
+ declare function Pagination({ paginator, class: className }: PaginationProps): Htmlable;
1585
+
1586
+ export { type DatabaseTestOptions as $, UploadValidationError as A, BusFake as B, Component as C, WithPagination as D, EventFake as E, FileNotPreviewableError as F, componentName as G, live as H, InvalidLiveRequestError as I, persistentMiddleware as J, AnonymousNotifiable as K, Live as L, MailFake as M, NotificationFake as N, On as O, PERSISTENT_MIDDLEWARE as P, QueueFake as Q, AssertableInertia as R, StorageFake as S, TEMPORARY_UPLOAD_DEFAULTS as T, UPDATE_URI as U, AssertableJson as V, WithFileUploads as W, type BatchRecord as X, type BootOptions as Y, type CountOrFilter as Z, DatabaseMigrations as _, type ComponentResult as a, DatabaseTransactions as a0, type DispatchedEvent as a1, type ExpectedErrors as a2, type ExpectedListener as a3, FakeDisk as a4, FakeFile as a5, HttpClient as a6, InteractsWithApplication as a7, InteractsWithConsole as a8, InteractsWithDatabase as a9, cookiePrefix as aA, decryptCookie as aB, encryptCookie as aC, flatten as aD, freezeSecond as aE, freezeTime as aF, guessMimeType as aG, inertiaPageOf as aH, install as aI, isExpired as aJ, matches as aK, nameOf as aL, recordingExceptionHandler as aM, recordingViewFactory as aN, responseCookies as aO, runCommand as aP, travel as aQ, travelBack as aR, travelTo as aS, usingInMemoryDatabase as aT, InteractsWithTime as aa, type JsonStructure as ab, MailRecord as ac, MakesHttpRequests as ad, PendingCommand as ae, type PushedJob as af, RefreshDatabase as ag, RefreshDatabaseState as ah, type RequestData as ai, type RequestOptions as aj, type ResponseContext as ak, type ResponseCookie as al, type SentNotification as am, TESTING_ENVIRONMENT as an, type TableOrModel as ao, type Target as ap, TestCase as aq, type TestHooks as ar, TestResponse as as, type TestTrait as at, type TravelDate as au, Wormhole as av, actingAsAuthFactory as aw, addresses as ax, applyEnvironment as ay, cookieHeader as az, Computed as b, CorruptComponentPayloadError as c, ErrorBag as d, InvalidUploadSignatureError as e, LiveComponentManager as f, LiveComponentNotFoundError as g, LiveError as h, type LiveProps as i, LiveServiceProvider as j, Locked as k, MethodNotCallableError as l, PREVIEW_URI as m, type Paginated as n, Pagination as o, type PaginationProps as p, type PaginationSource as q, PendingEvent as r, type PersistentMiddleware as s, PropertyNotUpdatableError as t, type TemporaryFileData as u, TemporaryFileNotFoundError as v, TemporaryUploadedFile as w, TestRequestScope as x, Testable as y, UPLOAD_URI as z };