@orchestr-sh/orchestr 1.6.0 → 1.7.0

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 (227) hide show
  1. package/README.md +289 -22
  2. package/dist/Console/Commands/EventCacheCommand.d.ts +15 -0
  3. package/dist/Console/Commands/EventCacheCommand.d.ts.map +1 -0
  4. package/dist/Console/Commands/EventCacheCommand.js +99 -0
  5. package/dist/Console/Commands/EventCacheCommand.js.map +1 -0
  6. package/dist/Console/Commands/EventClearCommand.d.ts +15 -0
  7. package/dist/Console/Commands/EventClearCommand.d.ts.map +1 -0
  8. package/dist/Console/Commands/EventClearCommand.js +71 -0
  9. package/dist/Console/Commands/EventClearCommand.js.map +1 -0
  10. package/dist/Console/Commands/EventListCommand.d.ts +19 -0
  11. package/dist/Console/Commands/EventListCommand.d.ts.map +1 -0
  12. package/dist/Console/Commands/EventListCommand.js +106 -0
  13. package/dist/Console/Commands/EventListCommand.js.map +1 -0
  14. package/dist/Console/Commands/MakeEventCommand.d.ts +27 -0
  15. package/dist/Console/Commands/MakeEventCommand.d.ts.map +1 -0
  16. package/dist/Console/Commands/MakeEventCommand.js +117 -0
  17. package/dist/Console/Commands/MakeEventCommand.js.map +1 -0
  18. package/dist/Console/Commands/MakeListenerCommand.d.ts +27 -0
  19. package/dist/Console/Commands/MakeListenerCommand.d.ts.map +1 -0
  20. package/dist/Console/Commands/MakeListenerCommand.js +157 -0
  21. package/dist/Console/Commands/MakeListenerCommand.js.map +1 -0
  22. package/dist/Console/Commands/MigrateStatusCommand.d.ts.map +1 -1
  23. package/dist/Console/Commands/MigrateStatusCommand.js.map +1 -1
  24. package/dist/Console/orchestr.js +10 -0
  25. package/dist/Console/orchestr.js.map +1 -1
  26. package/dist/Container/Container.js.map +1 -1
  27. package/dist/Contracts/Events/Dispatcher.d.ts +94 -0
  28. package/dist/Contracts/Events/Dispatcher.d.ts.map +1 -0
  29. package/dist/Contracts/Events/Dispatcher.js +9 -0
  30. package/dist/Contracts/Events/Dispatcher.js.map +1 -0
  31. package/dist/Contracts/Events/index.d.ts +7 -0
  32. package/dist/Contracts/Events/index.d.ts.map +1 -0
  33. package/dist/Contracts/Events/index.js +8 -0
  34. package/dist/Contracts/Events/index.js.map +1 -0
  35. package/dist/Database/Connection.d.ts.map +1 -1
  36. package/dist/Database/Connection.js.map +1 -1
  37. package/dist/Database/Ensemble/Concerns/HasDynamicRelations.d.ts.map +1 -1
  38. package/dist/Database/Ensemble/Concerns/HasDynamicRelations.js +43 -12
  39. package/dist/Database/Ensemble/Concerns/HasDynamicRelations.js.map +1 -1
  40. package/dist/Database/Ensemble/Concerns/HasRelationships.d.ts.map +1 -1
  41. package/dist/Database/Ensemble/Concerns/HasRelationships.js +2 -5
  42. package/dist/Database/Ensemble/Concerns/HasRelationships.js.map +1 -1
  43. package/dist/Database/Ensemble/Ensemble.d.ts +7 -0
  44. package/dist/Database/Ensemble/Ensemble.d.ts.map +1 -1
  45. package/dist/Database/Ensemble/Ensemble.js +134 -11
  46. package/dist/Database/Ensemble/Ensemble.js.map +1 -1
  47. package/dist/Database/Ensemble/EnsembleBuilder.d.ts.map +1 -1
  48. package/dist/Database/Ensemble/EnsembleBuilder.js +7 -0
  49. package/dist/Database/Ensemble/EnsembleBuilder.js.map +1 -1
  50. package/dist/Database/Ensemble/Events/ModelCreated.d.ts +11 -0
  51. package/dist/Database/Ensemble/Events/ModelCreated.d.ts.map +1 -0
  52. package/dist/Database/Ensemble/Events/ModelCreated.js +16 -0
  53. package/dist/Database/Ensemble/Events/ModelCreated.js.map +1 -0
  54. package/dist/Database/Ensemble/Events/ModelCreating.d.ts +12 -0
  55. package/dist/Database/Ensemble/Events/ModelCreating.d.ts.map +1 -0
  56. package/dist/Database/Ensemble/Events/ModelCreating.js +17 -0
  57. package/dist/Database/Ensemble/Events/ModelCreating.js.map +1 -0
  58. package/dist/Database/Ensemble/Events/ModelDeleted.d.ts +11 -0
  59. package/dist/Database/Ensemble/Events/ModelDeleted.d.ts.map +1 -0
  60. package/dist/Database/Ensemble/Events/ModelDeleted.js +16 -0
  61. package/dist/Database/Ensemble/Events/ModelDeleted.js.map +1 -0
  62. package/dist/Database/Ensemble/Events/ModelDeleting.d.ts +12 -0
  63. package/dist/Database/Ensemble/Events/ModelDeleting.d.ts.map +1 -0
  64. package/dist/Database/Ensemble/Events/ModelDeleting.js +17 -0
  65. package/dist/Database/Ensemble/Events/ModelDeleting.js.map +1 -0
  66. package/dist/Database/Ensemble/Events/ModelEvent.d.ts +17 -0
  67. package/dist/Database/Ensemble/Events/ModelEvent.d.ts.map +1 -0
  68. package/dist/Database/Ensemble/Events/ModelEvent.js +22 -0
  69. package/dist/Database/Ensemble/Events/ModelEvent.js.map +1 -0
  70. package/dist/Database/Ensemble/Events/ModelRetrieved.d.ts +11 -0
  71. package/dist/Database/Ensemble/Events/ModelRetrieved.d.ts.map +1 -0
  72. package/dist/Database/Ensemble/Events/ModelRetrieved.js +16 -0
  73. package/dist/Database/Ensemble/Events/ModelRetrieved.js.map +1 -0
  74. package/dist/Database/Ensemble/Events/ModelSaved.d.ts +11 -0
  75. package/dist/Database/Ensemble/Events/ModelSaved.d.ts.map +1 -0
  76. package/dist/Database/Ensemble/Events/ModelSaved.js +16 -0
  77. package/dist/Database/Ensemble/Events/ModelSaved.js.map +1 -0
  78. package/dist/Database/Ensemble/Events/ModelSaving.d.ts +12 -0
  79. package/dist/Database/Ensemble/Events/ModelSaving.d.ts.map +1 -0
  80. package/dist/Database/Ensemble/Events/ModelSaving.js +17 -0
  81. package/dist/Database/Ensemble/Events/ModelSaving.js.map +1 -0
  82. package/dist/Database/Ensemble/Events/ModelUpdated.d.ts +11 -0
  83. package/dist/Database/Ensemble/Events/ModelUpdated.d.ts.map +1 -0
  84. package/dist/Database/Ensemble/Events/ModelUpdated.js +16 -0
  85. package/dist/Database/Ensemble/Events/ModelUpdated.js.map +1 -0
  86. package/dist/Database/Ensemble/Events/ModelUpdating.d.ts +12 -0
  87. package/dist/Database/Ensemble/Events/ModelUpdating.d.ts.map +1 -0
  88. package/dist/Database/Ensemble/Events/ModelUpdating.js +17 -0
  89. package/dist/Database/Ensemble/Events/ModelUpdating.js.map +1 -0
  90. package/dist/Database/Ensemble/Events/index.d.ts +16 -0
  91. package/dist/Database/Ensemble/Events/index.d.ts.map +1 -0
  92. package/dist/Database/Ensemble/Events/index.js +29 -0
  93. package/dist/Database/Ensemble/Events/index.js.map +1 -0
  94. package/dist/Database/Ensemble/Relations/BelongsTo.d.ts.map +1 -1
  95. package/dist/Database/Ensemble/Relations/BelongsTo.js.map +1 -1
  96. package/dist/Database/Ensemble/Relations/BelongsToMany.d.ts.map +1 -1
  97. package/dist/Database/Ensemble/Relations/BelongsToMany.js +1 -4
  98. package/dist/Database/Ensemble/Relations/BelongsToMany.js.map +1 -1
  99. package/dist/Database/Ensemble/Relations/HasMany.d.ts.map +1 -1
  100. package/dist/Database/Ensemble/Relations/HasMany.js.map +1 -1
  101. package/dist/Database/Ensemble/Relations/HasOne.d.ts.map +1 -1
  102. package/dist/Database/Ensemble/Relations/HasOne.js.map +1 -1
  103. package/dist/Database/Ensemble/Relations/MorphMany.d.ts.map +1 -1
  104. package/dist/Database/Ensemble/Relations/MorphMany.js +2 -6
  105. package/dist/Database/Ensemble/Relations/MorphMany.js.map +1 -1
  106. package/dist/Database/Ensemble/Relations/MorphOne.d.ts.map +1 -1
  107. package/dist/Database/Ensemble/Relations/MorphOne.js +2 -6
  108. package/dist/Database/Ensemble/Relations/MorphOne.js.map +1 -1
  109. package/dist/Database/Ensemble/Relations/MorphTo.d.ts.map +1 -1
  110. package/dist/Database/Ensemble/Relations/MorphTo.js +5 -11
  111. package/dist/Database/Ensemble/Relations/MorphTo.js.map +1 -1
  112. package/dist/Database/Ensemble/Relations/MorphToMany.d.ts.map +1 -1
  113. package/dist/Database/Ensemble/Relations/MorphToMany.js +1 -3
  114. package/dist/Database/Ensemble/Relations/MorphToMany.js.map +1 -1
  115. package/dist/Database/Ensemble/Relations/MorphedByMany.d.ts.map +1 -1
  116. package/dist/Database/Ensemble/Relations/MorphedByMany.js.map +1 -1
  117. package/dist/Database/Ensemble/Relations/Relation.d.ts.map +1 -1
  118. package/dist/Database/Ensemble/Relations/Relation.js +4 -2
  119. package/dist/Database/Ensemble/Relations/Relation.js.map +1 -1
  120. package/dist/Database/Migrations/MigrationRepository.d.ts.map +1 -1
  121. package/dist/Database/Migrations/MigrationRepository.js +4 -19
  122. package/dist/Database/Migrations/MigrationRepository.js.map +1 -1
  123. package/dist/Database/Migrations/SchemaBuilder.d.ts.map +1 -1
  124. package/dist/Database/Migrations/SchemaBuilder.js +5 -15
  125. package/dist/Database/Migrations/SchemaBuilder.js.map +1 -1
  126. package/dist/Database/Query/Builder.d.ts.map +1 -1
  127. package/dist/Database/Query/Builder.js +5 -4
  128. package/dist/Database/Query/Builder.js.map +1 -1
  129. package/dist/Events/Concerns/Dispatchable.d.ts +121 -0
  130. package/dist/Events/Concerns/Dispatchable.d.ts.map +1 -0
  131. package/dist/Events/Concerns/Dispatchable.js +165 -0
  132. package/dist/Events/Concerns/Dispatchable.js.map +1 -0
  133. package/dist/Events/Contracts/Dispatcher.d.ts +144 -0
  134. package/dist/Events/Contracts/Dispatcher.d.ts.map +1 -0
  135. package/dist/Events/Contracts/Dispatcher.js +3 -0
  136. package/dist/Events/Contracts/Dispatcher.js.map +1 -0
  137. package/dist/Events/Contracts/ShouldDispatchAfterCommit.d.ts +21 -0
  138. package/dist/Events/Contracts/ShouldDispatchAfterCommit.d.ts.map +1 -0
  139. package/dist/Events/Contracts/ShouldDispatchAfterCommit.js +3 -0
  140. package/dist/Events/Contracts/ShouldDispatchAfterCommit.js.map +1 -0
  141. package/dist/Events/Decorators/HandlesEvents.d.ts +83 -0
  142. package/dist/Events/Decorators/HandlesEvents.d.ts.map +1 -0
  143. package/dist/Events/Decorators/HandlesEvents.js +105 -0
  144. package/dist/Events/Decorators/HandlesEvents.js.map +1 -0
  145. package/dist/Events/Dispatcher.d.ts +201 -0
  146. package/dist/Events/Dispatcher.d.ts.map +1 -0
  147. package/dist/Events/Dispatcher.js +359 -0
  148. package/dist/Events/Dispatcher.js.map +1 -0
  149. package/dist/Events/Event.d.ts +140 -0
  150. package/dist/Events/Event.d.ts.map +1 -0
  151. package/dist/Events/Event.js +266 -0
  152. package/dist/Events/Event.js.map +1 -0
  153. package/dist/Events/EventDiscoveryCache.d.ts +205 -0
  154. package/dist/Events/EventDiscoveryCache.d.ts.map +1 -0
  155. package/dist/Events/EventDiscoveryCache.js +310 -0
  156. package/dist/Events/EventDiscoveryCache.js.map +1 -0
  157. package/dist/Events/EventServiceProvider.d.ts +148 -0
  158. package/dist/Events/EventServiceProvider.d.ts.map +1 -0
  159. package/dist/Events/EventServiceProvider.js +258 -0
  160. package/dist/Events/EventServiceProvider.js.map +1 -0
  161. package/dist/Events/NullDispatcher.d.ts +97 -0
  162. package/dist/Events/NullDispatcher.d.ts.map +1 -0
  163. package/dist/Events/NullDispatcher.js +118 -0
  164. package/dist/Events/NullDispatcher.js.map +1 -0
  165. package/dist/Events/PendingDispatch.d.ts +119 -0
  166. package/dist/Events/PendingDispatch.d.ts.map +1 -0
  167. package/dist/Events/PendingDispatch.js +162 -0
  168. package/dist/Events/PendingDispatch.js.map +1 -0
  169. package/dist/Events/index.d.ts +12 -0
  170. package/dist/Events/index.d.ts.map +1 -0
  171. package/dist/Events/index.js +20 -0
  172. package/dist/Events/index.js.map +1 -0
  173. package/dist/Events/types.d.ts +77 -0
  174. package/dist/Events/types.d.ts.map +1 -0
  175. package/dist/Events/types.js +3 -0
  176. package/dist/Events/types.js.map +1 -0
  177. package/dist/Facades/DB.d.ts.map +1 -1
  178. package/dist/Facades/DB.js.map +1 -1
  179. package/dist/Facades/Event.d.ts +200 -0
  180. package/dist/Facades/Event.d.ts.map +1 -0
  181. package/dist/Facades/Event.js +331 -0
  182. package/dist/Facades/Event.js.map +1 -0
  183. package/dist/Facades/Route.js +1 -1
  184. package/dist/Foundation/Application.d.ts +33 -0
  185. package/dist/Foundation/Application.d.ts.map +1 -1
  186. package/dist/Foundation/Application.js +43 -3
  187. package/dist/Foundation/Application.js.map +1 -1
  188. package/dist/Foundation/Config/Config.js +1 -1
  189. package/dist/Foundation/Config/Config.js.map +1 -1
  190. package/dist/Foundation/Http/FormRequest.d.ts.map +1 -1
  191. package/dist/Foundation/Http/FormRequest.js +2 -2
  192. package/dist/Foundation/Http/FormRequest.js.map +1 -1
  193. package/dist/Foundation/Http/Kernel.d.ts.map +1 -1
  194. package/dist/Foundation/Http/Kernel.js +1 -1
  195. package/dist/Foundation/Http/Kernel.js.map +1 -1
  196. package/dist/Foundation/Http/Validator.d.ts.map +1 -1
  197. package/dist/Foundation/Http/Validator.js +27 -22
  198. package/dist/Foundation/Http/Validator.js.map +1 -1
  199. package/dist/Listeners/Contracts/ShouldQueue.d.ts +142 -0
  200. package/dist/Listeners/Contracts/ShouldQueue.d.ts.map +1 -0
  201. package/dist/Listeners/Contracts/ShouldQueue.js +20 -0
  202. package/dist/Listeners/Contracts/ShouldQueue.js.map +1 -0
  203. package/dist/Listeners/Contracts/ShouldQueueAfterCommit.d.ts +24 -0
  204. package/dist/Listeners/Contracts/ShouldQueueAfterCommit.d.ts.map +1 -0
  205. package/dist/Listeners/Contracts/ShouldQueueAfterCommit.js +3 -0
  206. package/dist/Listeners/Contracts/ShouldQueueAfterCommit.js.map +1 -0
  207. package/dist/Routing/Request.js +1 -1
  208. package/dist/Routing/Request.js.map +1 -1
  209. package/dist/Routing/Route.js +1 -1
  210. package/dist/Routing/Route.js.map +1 -1
  211. package/dist/Routing/Router.d.ts.map +1 -1
  212. package/dist/Routing/Router.js +5 -6
  213. package/dist/Routing/Router.js.map +1 -1
  214. package/dist/Support/EventDiscovery.d.ts +142 -0
  215. package/dist/Support/EventDiscovery.d.ts.map +1 -0
  216. package/dist/Support/EventDiscovery.js +302 -0
  217. package/dist/Support/EventDiscovery.js.map +1 -0
  218. package/dist/Support/Facade.js +2 -2
  219. package/dist/Support/Testing/Fakes/EventFake.d.ts +291 -0
  220. package/dist/Support/Testing/Fakes/EventFake.d.ts.map +1 -0
  221. package/dist/Support/Testing/Fakes/EventFake.js +444 -0
  222. package/dist/Support/Testing/Fakes/EventFake.js.map +1 -0
  223. package/dist/index.d.ts +10 -4
  224. package/dist/index.d.ts.map +1 -1
  225. package/dist/index.js +11 -1
  226. package/dist/index.js.map +1 -1
  227. package/package.json +33 -12
package/README.md CHANGED
@@ -9,6 +9,37 @@ npm install @orchestr-sh/orchestr reflect-metadata drizzle-orm
9
9
  npm install better-sqlite3 # or your preferred database driver
10
10
  ```
11
11
 
12
+ ### CLI Setup
13
+
14
+ After installation, the `orchestr` command will be available in your project via `npx`:
15
+
16
+ ```bash
17
+ # Run orchestr commands
18
+ npx orchestr make:event UserRegistered
19
+ npx orchestr make:migration create_users_table
20
+ npx orchestr migrate
21
+
22
+ # Or add to package.json scripts for convenience
23
+ {
24
+ "scripts": {
25
+ "orchestr": "orchestr"
26
+ }
27
+ }
28
+
29
+ # Then run with npm
30
+ npm run orchestr make:event UserRegistered
31
+ ```
32
+
33
+ For global installation (optional):
34
+
35
+ ```bash
36
+ npm install -g @orchestr-sh/orchestr
37
+
38
+ # Now use orchestr directly
39
+ orchestr make:event UserRegistered
40
+ orchestr migrate
41
+ ```
42
+
12
43
  ## Quick Start
13
44
 
14
45
  ```typescript
@@ -224,25 +255,25 @@ Laravel-style migrations with a fluent Schema builder.
224
255
 
225
256
  ```bash
226
257
  # Create a migration
227
- orchestr make:migration create_users_table --create=users
258
+ npx orchestr make:migration create_users_table --create=users
228
259
 
229
260
  # Run migrations
230
- orchestr migrate
261
+ npx orchestr migrate
231
262
 
232
263
  # Rollback last batch
233
- orchestr migrate:rollback
264
+ npx orchestr migrate:rollback
234
265
 
235
266
  # Rollback all migrations
236
- orchestr migrate:reset
267
+ npx orchestr migrate:reset
237
268
 
238
269
  # Drop all tables and re-run migrations
239
- orchestr migrate:fresh
270
+ npx orchestr migrate:fresh
240
271
 
241
272
  # Rollback and re-run all migrations
242
- orchestr migrate:refresh
273
+ npx orchestr migrate:refresh
243
274
 
244
275
  # Check migration status
245
- orchestr migrate:status
276
+ npx orchestr migrate:status
246
277
  ```
247
278
 
248
279
  ### Creating Tables
@@ -310,13 +341,13 @@ Populate your database with test or initial data.
310
341
 
311
342
  ```bash
312
343
  # Create a seeder
313
- orchestr make:seeder UserSeeder
344
+ npx orchestr make:seeder UserSeeder
314
345
 
315
346
  # Run all seeders (runs DatabaseSeeder)
316
- orchestr db:seed
347
+ npx orchestr db:seed
317
348
 
318
349
  # Run a specific seeder
319
- orchestr db:seed --class=UserSeeder
350
+ npx orchestr db:seed --class=UserSeeder
320
351
  ```
321
352
 
322
353
  ### Creating Seeders
@@ -352,6 +383,227 @@ export default class DatabaseSeeder extends Seeder {
352
383
  }
353
384
  ```
354
385
 
386
+ ## Events and Listeners
387
+
388
+ Laravel-style event system with listeners, subscribers, and automatic discovery.
389
+
390
+ ### Creating Events
391
+
392
+ Events are simple classes that hold data about something that happened in your application.
393
+
394
+ ```typescript
395
+ import { Event } from '@orchestr-sh/orchestr';
396
+
397
+ export class UserRegistered extends Event {
398
+ constructor(public readonly user: User) {
399
+ super();
400
+ }
401
+ }
402
+
403
+ // Create via command
404
+ npx orchestr make:event UserRegistered
405
+ ```
406
+
407
+ ### Creating Listeners
408
+
409
+ Listeners handle events with a `handle` method.
410
+
411
+ ```typescript
412
+ export class SendWelcomeEmail {
413
+ handle(event: UserRegistered): void {
414
+ // Send welcome email to event.user
415
+ }
416
+ }
417
+
418
+ // Create via command
419
+ npx orchestr make:listener SendWelcomeEmail --event=UserRegistered
420
+ npx orchestr make:listener ProcessOrder --queued // For queued listeners
421
+ ```
422
+
423
+ ### Registering Events and Listeners
424
+
425
+ Register in your `EventServiceProvider`:
426
+
427
+ ```typescript
428
+ import { EventServiceProvider } from '@orchestr-sh/orchestr';
429
+
430
+ export class AppEventServiceProvider extends EventServiceProvider {
431
+ protected listen = {
432
+ 'UserRegistered': [
433
+ 'SendWelcomeEmail',
434
+ 'CreateUserProfile',
435
+ ],
436
+ 'OrderPlaced': 'SendOrderConfirmation',
437
+ };
438
+ }
439
+ ```
440
+
441
+ Or use the Event facade to register listeners dynamically:
442
+
443
+ ```typescript
444
+ import { Event } from '@orchestr-sh/orchestr';
445
+
446
+ // Class-based listener
447
+ Event.listen(UserRegistered, SendWelcomeEmail);
448
+
449
+ // Closure listener
450
+ Event.listen(UserRegistered, (event) => {
451
+ console.log(`User registered: ${event.user.email}`);
452
+ });
453
+
454
+ // Multiple events
455
+ Event.listen(['UserRegistered', 'UserUpdated'], LogUserActivity);
456
+
457
+ // Wildcard listeners
458
+ Event.listen('user.*', (event) => {
459
+ // Handles user.registered, user.updated, etc.
460
+ });
461
+ ```
462
+
463
+ ### Dispatching Events
464
+
465
+ ```typescript
466
+ import { Event } from '@orchestr-sh/orchestr';
467
+
468
+ // Dispatch via facade
469
+ Event.dispatch(new UserRegistered(user));
470
+
471
+ // Static dispatch on event class
472
+ UserRegistered.dispatch(user);
473
+
474
+ // Conditional dispatch
475
+ UserRegistered.dispatchIf(user.isActive, user);
476
+ UserRegistered.dispatchUnless(user.isAdmin, user);
477
+
478
+ // Dispatch until first non-null response (halting)
479
+ const result = UserRegistered.until(user);
480
+ if (result === false) {
481
+ // Listener vetoed the operation
482
+ }
483
+
484
+ // Queue events for later
485
+ Event.push('user.registered', [user]);
486
+ Event.flush('user.registered'); // Dispatch all queued
487
+ ```
488
+
489
+ ### Event Subscribers
490
+
491
+ Subscribers listen to multiple events in a single class:
492
+
493
+ ```typescript
494
+ import { EventSubscriber, Dispatcher } from '@orchestr-sh/orchestr';
495
+
496
+ export class UserEventSubscriber implements EventSubscriber {
497
+ subscribe(events: Dispatcher): void {
498
+ events.listen('UserRegistered', this.onRegistered.bind(this));
499
+ events.listen('UserUpdated', this.onUpdated.bind(this));
500
+ events.listen('user.*', this.logActivity.bind(this));
501
+ }
502
+
503
+ onRegistered(event: UserRegistered): void {
504
+ // Handle registration
505
+ }
506
+
507
+ onUpdated(event: UserUpdated): void {
508
+ // Handle update
509
+ }
510
+
511
+ logActivity(event: any): void {
512
+ // Log any user activity
513
+ }
514
+ }
515
+
516
+ // Register in EventServiceProvider
517
+ protected subscribe = [
518
+ 'UserEventSubscriber',
519
+ ];
520
+ ```
521
+
522
+ ### Model Events
523
+
524
+ Ensemble models automatically dispatch lifecycle events:
525
+
526
+ ```typescript
527
+ import { Event, ModelCreated, ModelUpdated, ModelDeleting } from '@orchestr-sh/orchestr';
528
+
529
+ // Listen to model events
530
+ Event.listen(ModelCreated, (event) => {
531
+ console.log('Model created:', event.model);
532
+ });
533
+
534
+ Event.listen(ModelDeleting, (event) => {
535
+ // Prevent deletion by returning false
536
+ if (event.model.isProtected) {
537
+ return false;
538
+ }
539
+ });
540
+
541
+ // Listen to specific model events using wildcards
542
+ Event.listen('User.*', (event) => {
543
+ // Handles all User model events
544
+ });
545
+ ```
546
+
547
+ Available model events:
548
+ - `ModelRetrieved` - After a model is retrieved from database
549
+ - `ModelCreating` - Before a model is created (can halt)
550
+ - `ModelCreated` - After a model is created
551
+ - `ModelUpdating` - Before a model is updated (can halt)
552
+ - `ModelUpdated` - After a model is updated
553
+ - `ModelSaving` - Before a model is saved (can halt)
554
+ - `ModelSaved` - After a model is saved
555
+ - `ModelDeleting` - Before a model is deleted (can halt)
556
+ - `ModelDeleted` - After a model is deleted
557
+
558
+ ### Testing Events
559
+
560
+ Use `Event.fake()` to test event dispatching:
561
+
562
+ ```typescript
563
+ import { Event } from '@orchestr-sh/orchestr';
564
+
565
+ // Fake all events
566
+ Event.fake();
567
+
568
+ // Your code that dispatches events
569
+ await userService.register(userData);
570
+
571
+ // Assert events were dispatched
572
+ Event.assertDispatched(UserRegistered);
573
+ Event.assertDispatched(UserRegistered, (event) => {
574
+ return event.user.email === 'test@example.com';
575
+ });
576
+ Event.assertDispatchedTimes(UserRegistered, 2);
577
+ Event.assertNotDispatched(UserDeleted);
578
+ Event.assertNothingDispatched();
579
+
580
+ // Fake specific events only
581
+ Event.fake([UserRegistered, OrderPlaced]);
582
+
583
+ // Fake all except specific events
584
+ Event.fakeExcept([UserDeleted]);
585
+
586
+ // Scoped faking
587
+ const [result, fake] = await Event.fakeFor(async (fake) => {
588
+ await someService.createUser();
589
+ return 'done';
590
+ });
591
+ fake.assertDispatched(UserRegistered);
592
+ ```
593
+
594
+ ### Console Commands
595
+
596
+ ```bash
597
+ # Create event
598
+ orchestr make:event UserRegistered
599
+ orchestr make:event OrderPlaced
600
+
601
+ # Create listener
602
+ orchestr make:listener SendWelcomeEmail
603
+ orchestr make:listener SendWelcomeEmail --event=UserRegistered
604
+ orchestr make:listener ProcessOrder --queued
605
+ ```
606
+
355
607
  ## Controllers
356
608
 
357
609
  ```typescript
@@ -579,22 +831,33 @@ table.softDeletes(column) // deleted_at timestamp
579
831
 
580
832
  ### CLI Commands
581
833
 
834
+ All commands should be run with `npx orchestr` (or just `orchestr` if installed globally):
835
+
582
836
  ```bash
583
837
  # Migrations
584
- orchestr make:migration <name> # Create migration
585
- orchestr make:migration <name> --create=<table> # Create table migration
586
- orchestr make:migration <name> --table=<table> # Update table migration
587
- orchestr migrate # Run migrations
588
- orchestr migrate:rollback # Rollback last batch
589
- orchestr migrate:reset # Rollback all migrations
590
- orchestr migrate:refresh # Reset and re-run migrations
591
- orchestr migrate:fresh # Drop all tables and migrate
592
- orchestr migrate:status # Show migration status
838
+ npx orchestr make:migration <name> # Create migration
839
+ npx orchestr make:migration <name> --create=<table> # Create table migration
840
+ npx orchestr make:migration <name> --table=<table> # Update table migration
841
+ npx orchestr migrate # Run migrations
842
+ npx orchestr migrate:rollback # Rollback last batch
843
+ npx orchestr migrate:reset # Rollback all migrations
844
+ npx orchestr migrate:refresh # Reset and re-run migrations
845
+ npx orchestr migrate:fresh # Drop all tables and migrate
846
+ npx orchestr migrate:status # Show migration status
593
847
 
594
848
  # Seeders
595
- orchestr make:seeder <name> # Create seeder
596
- orchestr db:seed # Run DatabaseSeeder
597
- orchestr db:seed --class=<name> # Run specific seeder
849
+ npx orchestr make:seeder <name> # Create seeder
850
+ npx orchestr db:seed # Run DatabaseSeeder
851
+ npx orchestr db:seed --class=<name> # Run specific seeder
852
+
853
+ # Events & Listeners
854
+ npx orchestr make:event <name> # Create event
855
+ npx orchestr make:listener <name> # Create listener
856
+ npx orchestr make:listener <name> --event=<EventName> # Create listener for event
857
+ npx orchestr make:listener <name> --queued # Create queued listener
858
+ npx orchestr event:list # List all registered events
859
+ npx orchestr event:cache # Cache discovered events
860
+ npx orchestr event:clear # Clear event cache
598
861
  ```
599
862
 
600
863
  ## Features
@@ -610,6 +873,10 @@ orchestr db:seed --class=<name> # Run specific seeder
610
873
  - ✅ Eager/Lazy Loading
611
874
  - ✅ Migrations with Schema Builder
612
875
  - ✅ Database Seeders
876
+ - ✅ Events & Listeners
877
+ - ✅ Event Subscribers
878
+ - ✅ Model Lifecycle Events
879
+ - ✅ Event Testing (Fakes & Assertions)
613
880
  - ✅ Soft Deletes
614
881
  - ✅ Attribute Casting
615
882
  - ✅ Timestamps
@@ -0,0 +1,15 @@
1
+ /**
2
+ * EventCacheCommand
3
+ *
4
+ * Discover and cache the application's events and listeners following Laravel's Artisan pattern
5
+ */
6
+ import { Command } from '../Command';
7
+ import { Application } from '../../Foundation/Application';
8
+ export declare class EventCacheCommand extends Command {
9
+ protected app: Application;
10
+ signature: string;
11
+ description: string;
12
+ constructor(app: Application);
13
+ handle(): Promise<void>;
14
+ }
15
+ //# sourceMappingURL=EventCacheCommand.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"EventCacheCommand.d.ts","sourceRoot":"","sources":["../../../src/Console/Commands/EventCacheCommand.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,OAAO,EAAE,MAAM,YAAY,CAAC;AACrC,OAAO,EAAE,WAAW,EAAE,MAAM,8BAA8B,CAAC;AAI3D,qBAAa,iBAAkB,SAAQ,OAAO;IAIhC,SAAS,CAAC,GAAG,EAAE,WAAW;IAHtC,SAAS,SAAiB;IAC1B,WAAW,SAAgE;gBAErD,GAAG,EAAE,WAAW;IAIhC,MAAM,IAAI,OAAO,CAAC,IAAI,CAAC;CAwD9B"}
@@ -0,0 +1,99 @@
1
+ "use strict";
2
+ /**
3
+ * EventCacheCommand
4
+ *
5
+ * Discover and cache the application's events and listeners following Laravel's Artisan pattern
6
+ */
7
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
8
+ if (k2 === undefined) k2 = k;
9
+ var desc = Object.getOwnPropertyDescriptor(m, k);
10
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
11
+ desc = { enumerable: true, get: function() { return m[k]; } };
12
+ }
13
+ Object.defineProperty(o, k2, desc);
14
+ }) : (function(o, m, k, k2) {
15
+ if (k2 === undefined) k2 = k;
16
+ o[k2] = m[k];
17
+ }));
18
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
19
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
20
+ }) : function(o, v) {
21
+ o["default"] = v;
22
+ });
23
+ var __importStar = (this && this.__importStar) || (function () {
24
+ var ownKeys = function(o) {
25
+ ownKeys = Object.getOwnPropertyNames || function (o) {
26
+ var ar = [];
27
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
28
+ return ar;
29
+ };
30
+ return ownKeys(o);
31
+ };
32
+ return function (mod) {
33
+ if (mod && mod.__esModule) return mod;
34
+ var result = {};
35
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
36
+ __setModuleDefault(result, mod);
37
+ return result;
38
+ };
39
+ })();
40
+ Object.defineProperty(exports, "__esModule", { value: true });
41
+ exports.EventCacheCommand = void 0;
42
+ const Command_1 = require("../Command");
43
+ const fs = __importStar(require("fs/promises"));
44
+ const path = __importStar(require("path"));
45
+ class EventCacheCommand extends Command_1.Command {
46
+ app;
47
+ signature = 'event:cache';
48
+ description = 'Discover and cache the application\'s events and listeners';
49
+ constructor(app) {
50
+ super();
51
+ this.app = app;
52
+ }
53
+ async handle() {
54
+ this.info('Discovering events and listeners...');
55
+ try {
56
+ // Try to dynamically import EventDiscovery (Task 6 dependency)
57
+ const { EventDiscovery } = await Promise.resolve().then(() => __importStar(require('../../Support/EventDiscovery')));
58
+ const discovery = new EventDiscovery(this.app);
59
+ const directories = this.app.getEventDiscoveryPaths();
60
+ this.comment(`Scanning directories:`);
61
+ directories.forEach(dir => this.comment(` - ${dir}`));
62
+ this.newLine();
63
+ const listeners = await discovery.discover(directories);
64
+ if (listeners.size === 0) {
65
+ this.warn('No events discovered.');
66
+ return;
67
+ }
68
+ // Convert Map to array for JSON serialization
69
+ const listenersArray = Array.from(listeners.entries());
70
+ // Create cache directory
71
+ const cachePath = this.app.storagePath('framework/events.json');
72
+ await fs.mkdir(path.dirname(cachePath), { recursive: true });
73
+ // Write cache file
74
+ await fs.writeFile(cachePath, JSON.stringify(listenersArray, null, 2));
75
+ this.info(`Events cached successfully!`);
76
+ this.newLine();
77
+ this.comment(`Cached ${listeners.size} events to: ${cachePath}`);
78
+ // Show summary
79
+ let totalListeners = 0;
80
+ for (const [, listenerList] of listeners) {
81
+ totalListeners += listenerList.length;
82
+ }
83
+ this.comment(`Total listeners: ${totalListeners}`);
84
+ }
85
+ catch (error) {
86
+ if (error.code === 'MODULE_NOT_FOUND' && error.message?.includes('EventDiscovery')) {
87
+ this.error('EventDiscovery module not found.');
88
+ this.comment('The EventDiscovery system (Task 6) must be implemented first.');
89
+ this.comment('This command will work once EventDiscovery is available.');
90
+ }
91
+ else {
92
+ this.error(`Failed to cache events: ${error.message}`);
93
+ throw error;
94
+ }
95
+ }
96
+ }
97
+ }
98
+ exports.EventCacheCommand = EventCacheCommand;
99
+ //# sourceMappingURL=EventCacheCommand.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"EventCacheCommand.js","sourceRoot":"","sources":["../../../src/Console/Commands/EventCacheCommand.ts"],"names":[],"mappings":";AAAA;;;;GAIG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAEH,wCAAqC;AAErC,gDAAkC;AAClC,2CAA6B;AAE7B,MAAa,iBAAkB,SAAQ,iBAAO;IAItB;IAHtB,SAAS,GAAG,aAAa,CAAC;IAC1B,WAAW,GAAG,4DAA4D,CAAC;IAE3E,YAAsB,GAAgB;QACpC,KAAK,EAAE,CAAC;QADY,QAAG,GAAH,GAAG,CAAa;IAEtC,CAAC;IAED,KAAK,CAAC,MAAM;QACV,IAAI,CAAC,IAAI,CAAC,qCAAqC,CAAC,CAAC;QAEjD,IAAI,CAAC;YACH,+DAA+D;YAC/D,MAAM,EAAE,cAAc,EAAE,GAAG,wDAAa,8BAA8B,GAAC,CAAC;YAExE,MAAM,SAAS,GAAG,IAAI,cAAc,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;YAC/C,MAAM,WAAW,GAAG,IAAI,CAAC,GAAG,CAAC,sBAAsB,EAAE,CAAC;YAEtD,IAAI,CAAC,OAAO,CAAC,uBAAuB,CAAC,CAAC;YACtC,WAAW,CAAC,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,IAAI,CAAC,OAAO,CAAC,OAAO,GAAG,EAAE,CAAC,CAAC,CAAC;YACvD,IAAI,CAAC,OAAO,EAAE,CAAC;YAEf,MAAM,SAAS,GAAG,MAAM,SAAS,CAAC,QAAQ,CAAC,WAAW,CAAC,CAAC;YAExD,IAAI,SAAS,CAAC,IAAI,KAAK,CAAC,EAAE,CAAC;gBACzB,IAAI,CAAC,IAAI,CAAC,uBAAuB,CAAC,CAAC;gBACnC,OAAO;YACT,CAAC;YAED,8CAA8C;YAC9C,MAAM,cAAc,GAAG,KAAK,CAAC,IAAI,CAAC,SAAS,CAAC,OAAO,EAAE,CAAC,CAAC;YAEvD,yBAAyB;YACzB,MAAM,SAAS,GAAG,IAAI,CAAC,GAAG,CAAC,WAAW,CAAC,uBAAuB,CAAC,CAAC;YAChE,MAAM,EAAE,CAAC,KAAK,CAAC,IAAI,CAAC,OAAO,CAAC,SAAS,CAAC,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;YAE7D,mBAAmB;YACnB,MAAM,EAAE,CAAC,SAAS,CAChB,SAAS,EACT,IAAI,CAAC,SAAS,CAAC,cAAc,EAAE,IAAI,EAAE,CAAC,CAAC,CACxC,CAAC;YAEF,IAAI,CAAC,IAAI,CAAC,6BAA6B,CAAC,CAAC;YACzC,IAAI,CAAC,OAAO,EAAE,CAAC;YACf,IAAI,CAAC,OAAO,CAAC,UAAU,SAAS,CAAC,IAAI,eAAe,SAAS,EAAE,CAAC,CAAC;YAEjE,eAAe;YACf,IAAI,cAAc,GAAG,CAAC,CAAC;YACvB,KAAK,MAAM,CAAC,EAAE,YAAY,CAAC,IAAI,SAAS,EAAE,CAAC;gBACzC,cAAc,IAAI,YAAY,CAAC,MAAM,CAAC;YACxC,CAAC;YAED,IAAI,CAAC,OAAO,CAAC,oBAAoB,cAAc,EAAE,CAAC,CAAC;QACrD,CAAC;QAAC,OAAO,KAAU,EAAE,CAAC;YACpB,IAAI,KAAK,CAAC,IAAI,KAAK,kBAAkB,IAAI,KAAK,CAAC,OAAO,EAAE,QAAQ,CAAC,gBAAgB,CAAC,EAAE,CAAC;gBACnF,IAAI,CAAC,KAAK,CAAC,kCAAkC,CAAC,CAAC;gBAC/C,IAAI,CAAC,OAAO,CAAC,+DAA+D,CAAC,CAAC;gBAC9E,IAAI,CAAC,OAAO,CAAC,0DAA0D,CAAC,CAAC;YAC3E,CAAC;iBAAM,CAAC;gBACN,IAAI,CAAC,KAAK,CAAC,2BAA2B,KAAK,CAAC,OAAO,EAAE,CAAC,CAAC;gBACvD,MAAM,KAAK,CAAC;YACd,CAAC;QACH,CAAC;IACH,CAAC;CACF;AAhED,8CAgEC"}
@@ -0,0 +1,15 @@
1
+ /**
2
+ * EventClearCommand
3
+ *
4
+ * Clear all cached events and listeners following Laravel's Artisan pattern
5
+ */
6
+ import { Command } from '../Command';
7
+ import { Application } from '../../Foundation/Application';
8
+ export declare class EventClearCommand extends Command {
9
+ protected app: Application;
10
+ signature: string;
11
+ description: string;
12
+ constructor(app: Application);
13
+ handle(): Promise<void>;
14
+ }
15
+ //# sourceMappingURL=EventClearCommand.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"EventClearCommand.d.ts","sourceRoot":"","sources":["../../../src/Console/Commands/EventClearCommand.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,OAAO,EAAE,MAAM,YAAY,CAAC;AACrC,OAAO,EAAE,WAAW,EAAE,MAAM,8BAA8B,CAAC;AAG3D,qBAAa,iBAAkB,SAAQ,OAAO;IAIhC,SAAS,CAAC,GAAG,EAAE,WAAW;IAHtC,SAAS,SAAiB;IAC1B,WAAW,SAA2C;gBAEhC,GAAG,EAAE,WAAW;IAIhC,MAAM,IAAI,OAAO,CAAC,IAAI,CAAC;CAgB9B"}
@@ -0,0 +1,71 @@
1
+ "use strict";
2
+ /**
3
+ * EventClearCommand
4
+ *
5
+ * Clear all cached events and listeners following Laravel's Artisan pattern
6
+ */
7
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
8
+ if (k2 === undefined) k2 = k;
9
+ var desc = Object.getOwnPropertyDescriptor(m, k);
10
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
11
+ desc = { enumerable: true, get: function() { return m[k]; } };
12
+ }
13
+ Object.defineProperty(o, k2, desc);
14
+ }) : (function(o, m, k, k2) {
15
+ if (k2 === undefined) k2 = k;
16
+ o[k2] = m[k];
17
+ }));
18
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
19
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
20
+ }) : function(o, v) {
21
+ o["default"] = v;
22
+ });
23
+ var __importStar = (this && this.__importStar) || (function () {
24
+ var ownKeys = function(o) {
25
+ ownKeys = Object.getOwnPropertyNames || function (o) {
26
+ var ar = [];
27
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
28
+ return ar;
29
+ };
30
+ return ownKeys(o);
31
+ };
32
+ return function (mod) {
33
+ if (mod && mod.__esModule) return mod;
34
+ var result = {};
35
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
36
+ __setModuleDefault(result, mod);
37
+ return result;
38
+ };
39
+ })();
40
+ Object.defineProperty(exports, "__esModule", { value: true });
41
+ exports.EventClearCommand = void 0;
42
+ const Command_1 = require("../Command");
43
+ const fs = __importStar(require("fs/promises"));
44
+ class EventClearCommand extends Command_1.Command {
45
+ app;
46
+ signature = 'event:clear';
47
+ description = 'Clear all cached events and listeners';
48
+ constructor(app) {
49
+ super();
50
+ this.app = app;
51
+ }
52
+ async handle() {
53
+ const cachePath = this.app.storagePath('framework/events.json');
54
+ try {
55
+ await fs.access(cachePath);
56
+ await fs.unlink(cachePath);
57
+ this.info('Cached events cleared successfully.');
58
+ }
59
+ catch (error) {
60
+ if (error.code === 'ENOENT') {
61
+ this.comment('No cached events found.');
62
+ }
63
+ else {
64
+ this.error(`Failed to clear cached events: ${error.message}`);
65
+ throw error;
66
+ }
67
+ }
68
+ }
69
+ }
70
+ exports.EventClearCommand = EventClearCommand;
71
+ //# sourceMappingURL=EventClearCommand.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"EventClearCommand.js","sourceRoot":"","sources":["../../../src/Console/Commands/EventClearCommand.ts"],"names":[],"mappings":";AAAA;;;;GAIG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAEH,wCAAqC;AAErC,gDAAkC;AAElC,MAAa,iBAAkB,SAAQ,iBAAO;IAItB;IAHtB,SAAS,GAAG,aAAa,CAAC;IAC1B,WAAW,GAAG,uCAAuC,CAAC;IAEtD,YAAsB,GAAgB;QACpC,KAAK,EAAE,CAAC;QADY,QAAG,GAAH,GAAG,CAAa;IAEtC,CAAC;IAED,KAAK,CAAC,MAAM;QACV,MAAM,SAAS,GAAG,IAAI,CAAC,GAAG,CAAC,WAAW,CAAC,uBAAuB,CAAC,CAAC;QAEhE,IAAI,CAAC;YACH,MAAM,EAAE,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC;YAC3B,MAAM,EAAE,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC;YAC3B,IAAI,CAAC,IAAI,CAAC,qCAAqC,CAAC,CAAC;QACnD,CAAC;QAAC,OAAO,KAAU,EAAE,CAAC;YACpB,IAAI,KAAK,CAAC,IAAI,KAAK,QAAQ,EAAE,CAAC;gBAC5B,IAAI,CAAC,OAAO,CAAC,yBAAyB,CAAC,CAAC;YAC1C,CAAC;iBAAM,CAAC;gBACN,IAAI,CAAC,KAAK,CAAC,kCAAkC,KAAK,CAAC,OAAO,EAAE,CAAC,CAAC;gBAC9D,MAAM,KAAK,CAAC;YACd,CAAC;QACH,CAAC;IACH,CAAC;CACF;AAxBD,8CAwBC"}
@@ -0,0 +1,19 @@
1
+ /**
2
+ * EventListCommand
3
+ *
4
+ * List all registered events and their listeners following Laravel's Artisan pattern
5
+ */
6
+ import { Command, CommandOptions } from '../Command';
7
+ import { Application } from '../../Foundation/Application';
8
+ export declare class EventListCommand extends Command {
9
+ protected app: Application;
10
+ signature: string;
11
+ description: string;
12
+ constructor(app: Application);
13
+ handle(args: string[], options: CommandOptions): Promise<void>;
14
+ /**
15
+ * Format a listener for display
16
+ */
17
+ protected formatListener(listener: any): string;
18
+ }
19
+ //# sourceMappingURL=EventListCommand.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"EventListCommand.d.ts","sourceRoot":"","sources":["../../../src/Console/Commands/EventListCommand.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,OAAO,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AACrD,OAAO,EAAE,WAAW,EAAE,MAAM,8BAA8B,CAAC;AAE3D,qBAAa,gBAAiB,SAAQ,OAAO;IAI/B,SAAS,CAAC,GAAG,EAAE,WAAW;IAHtC,SAAS,SAA2B;IACpC,WAAW,SAAkD;gBAEvC,GAAG,EAAE,WAAW;IAIhC,MAAM,CAAC,IAAI,EAAE,MAAM,EAAE,EAAE,OAAO,EAAE,cAAc,GAAG,OAAO,CAAC,IAAI,CAAC;IA2FpE;;OAEG;IACH,SAAS,CAAC,cAAc,CAAC,QAAQ,EAAE,GAAG,GAAG,MAAM;CAehD"}