@nymphjs/nymph 1.0.0-beta.3 → 1.0.0-beta.31

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.
package/src/Nymph.ts CHANGED
@@ -1,7 +1,7 @@
1
1
  import { Config, ConfigDefaults as defaults } from './conf';
2
- import { NymphDriver } from './driver';
2
+ import type { NymphDriver } from './driver';
3
3
  import Entity from './Entity';
4
- import { EntityConstructor, EntityData, EntityInterface } from './Entity.types';
4
+ import type { EntityConstructor, EntityInterface } from './Entity.types';
5
5
  import { ClassNotAvailableError } from './errors';
6
6
  import type {
7
7
  Selector,
@@ -12,18 +12,31 @@ import type {
12
12
  NymphBeforeGetEntitiesCallback,
13
13
  NymphBeforeSaveEntityCallback,
14
14
  NymphAfterSaveEntityCallback,
15
+ NymphFailedSaveEntityCallback,
15
16
  NymphBeforeDeleteEntityCallback,
16
17
  NymphAfterDeleteEntityCallback,
18
+ NymphFailedDeleteEntityCallback,
17
19
  NymphBeforeDeleteEntityByIDCallback,
18
20
  NymphAfterDeleteEntityByIDCallback,
21
+ NymphFailedDeleteEntityByIDCallback,
19
22
  NymphBeforeNewUIDCallback,
20
23
  NymphAfterNewUIDCallback,
24
+ NymphFailedNewUIDCallback,
21
25
  NymphBeforeSetUIDCallback,
22
26
  NymphAfterSetUIDCallback,
27
+ NymphFailedSetUIDCallback,
23
28
  NymphBeforeRenameUIDCallback,
24
29
  NymphAfterRenameUIDCallback,
30
+ NymphFailedRenameUIDCallback,
25
31
  NymphBeforeDeleteUIDCallback,
26
32
  NymphAfterDeleteUIDCallback,
33
+ NymphFailedDeleteUIDCallback,
34
+ NymphBeforeStartTransactionCallback,
35
+ NymphAfterStartTransactionCallback,
36
+ NymphBeforeCommitTransactionCallback,
37
+ NymphAfterCommitTransactionCallback,
38
+ NymphBeforeRollbackTransactionCallback,
39
+ NymphAfterRollbackTransactionCallback,
27
40
  NymphEventType,
28
41
  NymphQueryCallback,
29
42
  FormattedSelector,
@@ -41,10 +54,16 @@ import type {
41
54
  */
42
55
  export default class Nymph {
43
56
  /**
44
- * The PubSub config.
57
+ * The Nymph config.
45
58
  */
46
59
  public config: Config;
47
60
 
61
+ /**
62
+ * The Nymph instance that this one was cloned from, or null if it's not a
63
+ * clone.
64
+ */
65
+ public parent: Nymph | null;
66
+
48
67
  /**
49
68
  * The Nymph database driver.
50
69
  */
@@ -63,7 +82,7 @@ export default class Nymph {
63
82
  /**
64
83
  * The entity class for this instance of Nymph.
65
84
  */
66
- public Entity: typeof Entity = Entity;
85
+ public Entity: typeof Entity;
67
86
 
68
87
  private connectCallbacks: NymphConnectCallback[] = [];
69
88
  private disconnectCallbacks: NymphDisconnectCallback[] = [];
@@ -72,34 +91,40 @@ export default class Nymph {
72
91
  private beforeGetEntitiesCallbacks: NymphBeforeGetEntitiesCallback[] = [];
73
92
  private beforeSaveEntityCallbacks: NymphBeforeSaveEntityCallback[] = [];
74
93
  private afterSaveEntityCallbacks: NymphAfterSaveEntityCallback[] = [];
94
+ private failedSaveEntityCallbacks: NymphFailedSaveEntityCallback[] = [];
75
95
  private beforeDeleteEntityCallbacks: NymphBeforeDeleteEntityCallback[] = [];
76
96
  private afterDeleteEntityCallbacks: NymphAfterDeleteEntityCallback[] = [];
97
+ private failedDeleteEntityCallbacks: NymphFailedDeleteEntityCallback[] = [];
77
98
  private beforeDeleteEntityByIDCallbacks: NymphBeforeDeleteEntityByIDCallback[] =
78
99
  [];
79
100
  private afterDeleteEntityByIDCallbacks: NymphAfterDeleteEntityByIDCallback[] =
80
101
  [];
102
+ private failedDeleteEntityByIDCallbacks: NymphFailedDeleteEntityByIDCallback[] =
103
+ [];
81
104
  private beforeNewUIDCallbacks: NymphBeforeNewUIDCallback[] = [];
82
105
  private afterNewUIDCallbacks: NymphAfterNewUIDCallback[] = [];
106
+ private failedNewUIDCallbacks: NymphFailedNewUIDCallback[] = [];
83
107
  private beforeSetUIDCallbacks: NymphBeforeSetUIDCallback[] = [];
84
108
  private afterSetUIDCallbacks: NymphAfterSetUIDCallback[] = [];
109
+ private failedSetUIDCallbacks: NymphFailedSetUIDCallback[] = [];
85
110
  private beforeRenameUIDCallbacks: NymphBeforeRenameUIDCallback[] = [];
86
111
  private afterRenameUIDCallbacks: NymphAfterRenameUIDCallback[] = [];
112
+ private failedRenameUIDCallbacks: NymphFailedRenameUIDCallback[] = [];
87
113
  private beforeDeleteUIDCallbacks: NymphBeforeDeleteUIDCallback[] = [];
88
114
  private afterDeleteUIDCallbacks: NymphAfterDeleteUIDCallback[] = [];
89
-
90
- public addEntityClass(entityClass: EntityConstructor) {
91
- this.entityClasses[entityClass.class] = entityClass;
92
- entityClass.nymph = this;
93
- }
94
-
95
- public getEntityClass(className: string): EntityConstructor {
96
- if (className in this.entityClasses) {
97
- const EntityClass = this.entityClasses[className];
98
- EntityClass.nymph = this;
99
- return EntityClass;
100
- }
101
- throw new ClassNotAvailableError('Tried to use class: ' + className);
102
- }
115
+ private failedDeleteUIDCallbacks: NymphFailedDeleteUIDCallback[] = [];
116
+ private beforeStartTransactionCallbacks: NymphBeforeStartTransactionCallback[] =
117
+ [];
118
+ private afterStartTransactionCallbacks: NymphAfterStartTransactionCallback[] =
119
+ [];
120
+ private beforeCommitTransactionCallbacks: NymphBeforeCommitTransactionCallback[] =
121
+ [];
122
+ private afterCommitTransactionCallbacks: NymphAfterCommitTransactionCallback[] =
123
+ [];
124
+ private beforeRollbackTransactionCallbacks: NymphBeforeRollbackTransactionCallback[] =
125
+ [];
126
+ private afterRollbackTransactionCallbacks: NymphAfterRollbackTransactionCallback[] =
127
+ [];
103
128
 
104
129
  /**
105
130
  * Initialize Nymph.
@@ -111,18 +136,77 @@ export default class Nymph {
111
136
  public constructor(
112
137
  config: Partial<Config>,
113
138
  driver: NymphDriver,
114
- tilmeld?: TilmeldInterface
139
+ tilmeld?: TilmeldInterface,
140
+ parent?: Nymph
115
141
  ) {
116
142
  this.config = { ...defaults, ...config };
117
143
  this.driver = driver;
118
- if (typeof tilmeld !== 'undefined') {
119
- this.tilmeld = tilmeld;
144
+ this.parent = parent ?? null;
145
+
146
+ this.Entity = this.addEntityClass(Entity);
147
+
148
+ if (parent) {
149
+ for (const name in parent.entityClasses) {
150
+ if (
151
+ name === 'Entity' ||
152
+ (parent.entityClasses[name] as any).skipOnClone
153
+ ) {
154
+ continue;
155
+ }
156
+ this.addEntityClass(parent.entityClasses[name]);
157
+ }
158
+
159
+ const events = [
160
+ 'connect',
161
+ 'disconnect',
162
+ 'query',
163
+ 'beforeGetEntity',
164
+ 'beforeGetEntities',
165
+ 'beforeSaveEntity',
166
+ 'afterSaveEntity',
167
+ 'failedSaveEntity',
168
+ 'beforeDeleteEntity',
169
+ 'afterDeleteEntity',
170
+ 'failedDeleteEntity',
171
+ 'beforeDeleteEntityByID',
172
+ 'afterDeleteEntityByID',
173
+ 'failedDeleteEntityByID',
174
+ 'beforeNewUID',
175
+ 'afterNewUID',
176
+ 'failedNewUID',
177
+ 'beforeSetUID',
178
+ 'afterSetUID',
179
+ 'failedSetUID',
180
+ 'beforeRenameUID',
181
+ 'afterRenameUID',
182
+ 'failedRenameUID',
183
+ 'beforeDeleteUID',
184
+ 'afterDeleteUID',
185
+ 'failedDeleteUID',
186
+ 'beforeStartTransaction',
187
+ 'afterStartTransaction',
188
+ 'beforeCommitTransaction',
189
+ 'afterCommitTransaction',
190
+ 'beforeRollbackTransaction',
191
+ 'afterRollbackTransaction',
192
+ ];
193
+
194
+ for (let event of events) {
195
+ const prop = event + 'Callbacks';
196
+ // @ts-ignore: The callback should be the right type here.
197
+ const callbacks = parent[prop];
198
+ for (let callback of callbacks) {
199
+ if (callback.skipOnClone) {
200
+ continue;
201
+ }
202
+ this.on(event as NymphEventType, callback);
203
+ }
204
+ }
120
205
  }
121
206
 
122
- class NymphEntity<T extends EntityData = EntityData> extends Entity<T> {}
123
- NymphEntity.nymph = this;
124
- this.Entity = NymphEntity;
125
- this.addEntityClass(NymphEntity);
207
+ if (tilmeld != null) {
208
+ this.tilmeld = tilmeld;
209
+ }
126
210
 
127
211
  this.driver.init(this);
128
212
  if (this.tilmeld) {
@@ -131,54 +215,60 @@ export default class Nymph {
131
215
  }
132
216
 
133
217
  /**
134
- * Get a clone of this instance with duplicate classes and event listeners.
218
+ * Add your class to this instance.
135
219
  *
136
- * @returns A clone of this instance.
220
+ * This will create a class that extends your class within this instance of
221
+ * Nymph and return it. You can then use this class's constructor and methods,
222
+ * which will use this instance of Nymph.
223
+ *
224
+ * Because this creates a subclass, don't use the class
225
+ * returned from `getEntityClass` to check with `instanceof`.
137
226
  */
138
- public clone() {
139
- const nymph = new Nymph(this.config, this.driver, this.tilmeld?.clone());
140
- for (const name in this.entityClasses) {
141
- if (name === 'Entity' || (this.entityClasses[name] as any).skipOnClone) {
142
- continue;
143
- }
144
- nymph.addEntityClass(this.entityClasses[name]);
145
- }
146
-
147
- const events = [
148
- 'connect',
149
- 'disconnect',
150
- 'query',
151
- 'beforeGetEntity',
152
- 'beforeGetEntities',
153
- 'beforeSaveEntity',
154
- 'afterSaveEntity',
155
- 'beforeDeleteEntity',
156
- 'afterDeleteEntity',
157
- 'beforeDeleteEntityByID',
158
- 'afterDeleteEntityByID',
159
- 'beforeNewUID',
160
- 'afterNewUID',
161
- 'beforeSetUID',
162
- 'afterSetUID',
163
- 'beforeRenameUID',
164
- 'afterRenameUID',
165
- 'beforeDeleteUID',
166
- 'afterDeleteUID',
167
- ];
168
-
169
- for (let event of events) {
170
- const prop = event + 'Callbacks';
171
- // @ts-ignore: The callback should be the right type here.
172
- const callbacks = this[prop];
173
- for (let callback of callbacks) {
174
- if (callback.skipOnClone) {
175
- continue;
176
- }
177
- nymph.on(event as NymphEventType, callback);
227
+ public addEntityClass<T extends EntityConstructor>(entityClass: T): T {
228
+ const nymph = this;
229
+ class NymphEntity extends entityClass {
230
+ static nymph: Nymph = nymph;
231
+
232
+ constructor(...args: any[]) {
233
+ super(...args);
178
234
  }
179
235
  }
236
+ this.entityClasses[entityClass.class] = NymphEntity;
237
+ return NymphEntity;
238
+ }
180
239
 
181
- return nymph;
240
+ /**
241
+ * Get the class that uses the specified class name.
242
+ */
243
+ public getEntityClass<T extends EntityConstructor>(className: T): T;
244
+ public getEntityClass(className: string): EntityConstructor;
245
+ public getEntityClass<T extends EntityConstructor = EntityConstructor>(
246
+ className: T | string
247
+ ): T | EntityConstructor {
248
+ let key: string | null = null;
249
+ if (typeof className === 'string') {
250
+ key = className;
251
+ } else {
252
+ key = className.class;
253
+ }
254
+ if (key in this.entityClasses) {
255
+ return this.entityClasses[key];
256
+ }
257
+ throw new ClassNotAvailableError('Tried to use class: ' + key);
258
+ }
259
+
260
+ /**
261
+ * Get a clone of this instance with duplicate classes and event listeners.
262
+ *
263
+ * @returns A clone of this instance.
264
+ */
265
+ public clone() {
266
+ return new Nymph(
267
+ this.config,
268
+ this.driver.clone(),
269
+ this.tilmeld?.clone(),
270
+ this
271
+ );
182
272
  }
183
273
 
184
274
  /**
@@ -232,28 +322,65 @@ export default class Nymph {
232
322
  * Transactions will nest as long as every name is unique. Internally, Nymph
233
323
  * uses names prefixed with "nymph-".
234
324
  *
235
- * @returns True on success, false on failure.
325
+ * @returns A new instance of Nymph that should be used for the transaction.
236
326
  */
237
327
  public async startTransaction(name: string): Promise<Nymph> {
238
- return await this.driver.startTransaction(name);
328
+ for (let callback of this.beforeStartTransactionCallbacks) {
329
+ if (callback) {
330
+ await callback(this, name);
331
+ }
332
+ }
333
+ const result = await this.driver.startTransaction(name);
334
+ for (let callback of this.afterStartTransactionCallbacks) {
335
+ if (callback) {
336
+ await callback(this, name, result);
337
+ }
338
+ }
339
+ return result;
239
340
  }
240
341
 
241
342
  /**
242
343
  * Commit the named transaction.
243
344
  *
345
+ * After this is called, the transaction instance should be discarded.
346
+ *
244
347
  * @returns True on success, false on failure.
245
348
  */
246
349
  public async commit(name: string): Promise<boolean> {
247
- return await this.driver.commit(name);
350
+ for (let callback of this.beforeCommitTransactionCallbacks) {
351
+ if (callback) {
352
+ await callback(this, name);
353
+ }
354
+ }
355
+ const result = await this.driver.commit(name);
356
+ for (let callback of this.afterCommitTransactionCallbacks) {
357
+ if (callback) {
358
+ await callback(this, name, result);
359
+ }
360
+ }
361
+ return result;
248
362
  }
249
363
 
250
364
  /**
251
365
  * Rollback the named transaction.
252
366
  *
367
+ * After this is called, the transaction instance should be discarded.
368
+ *
253
369
  * @returns True on success, false on failure.
254
370
  */
255
371
  public async rollback(name: string): Promise<boolean> {
256
- return await this.driver.rollback(name);
372
+ for (let callback of this.beforeRollbackTransactionCallbacks) {
373
+ if (callback) {
374
+ await callback(this, name);
375
+ }
376
+ }
377
+ const result = await this.driver.rollback(name);
378
+ for (let callback of this.afterRollbackTransactionCallbacks) {
379
+ if (callback) {
380
+ await callback(this, name, result);
381
+ }
382
+ }
383
+ return result;
257
384
  }
258
385
 
259
386
  /**
@@ -292,7 +419,17 @@ export default class Nymph {
292
419
  await callback(this, name);
293
420
  }
294
421
  }
295
- const result = this.driver.newUID(name);
422
+ let result: Promise<number | null>;
423
+ try {
424
+ result = this.driver.newUID(name);
425
+ } catch (e: any) {
426
+ for (let callback of this.failedNewUIDCallbacks) {
427
+ if (callback) {
428
+ await callback(this, e);
429
+ }
430
+ }
431
+ throw e;
432
+ }
296
433
  for (let callback of this.afterNewUIDCallbacks) {
297
434
  if (callback) {
298
435
  await callback(this, result);
@@ -323,7 +460,17 @@ export default class Nymph {
323
460
  await callback(this, name, value);
324
461
  }
325
462
  }
326
- const result = this.driver.setUID(name, value);
463
+ let result: Promise<boolean>;
464
+ try {
465
+ result = this.driver.setUID(name, value);
466
+ } catch (e: any) {
467
+ for (let callback of this.failedSetUIDCallbacks) {
468
+ if (callback) {
469
+ await callback(this, e);
470
+ }
471
+ }
472
+ throw e;
473
+ }
327
474
  for (let callback of this.afterSetUIDCallbacks) {
328
475
  if (callback) {
329
476
  await callback(this, result);
@@ -344,7 +491,17 @@ export default class Nymph {
344
491
  await callback(this, name);
345
492
  }
346
493
  }
347
- const result = this.driver.deleteUID(name);
494
+ let result: Promise<boolean>;
495
+ try {
496
+ result = this.driver.deleteUID(name);
497
+ } catch (e: any) {
498
+ for (let callback of this.failedDeleteUIDCallbacks) {
499
+ if (callback) {
500
+ await callback(this, e);
501
+ }
502
+ }
503
+ throw e;
504
+ }
348
505
  for (let callback of this.afterDeleteUIDCallbacks) {
349
506
  if (callback) {
350
507
  await callback(this, result);
@@ -366,7 +523,17 @@ export default class Nymph {
366
523
  await callback(this, oldName, newName);
367
524
  }
368
525
  }
369
- const result = this.driver.renameUID(oldName, newName);
526
+ let result: Promise<boolean>;
527
+ try {
528
+ result = this.driver.renameUID(oldName, newName);
529
+ } catch (e: any) {
530
+ for (let callback of this.failedRenameUIDCallbacks) {
531
+ if (callback) {
532
+ await callback(this, e);
533
+ }
534
+ }
535
+ throw e;
536
+ }
370
537
  for (let callback of this.afterRenameUIDCallbacks) {
371
538
  if (callback) {
372
539
  await callback(this, result);
@@ -392,7 +559,17 @@ export default class Nymph {
392
559
  await callback(this, entity);
393
560
  }
394
561
  }
395
- const result = this.driver.saveEntity(entity);
562
+ let result: Promise<boolean>;
563
+ try {
564
+ result = this.driver.saveEntity(entity);
565
+ } catch (e: any) {
566
+ for (let callback of this.failedSaveEntityCallbacks) {
567
+ if (callback) {
568
+ await callback(this, e);
569
+ }
570
+ }
571
+ throw e;
572
+ }
396
573
  for (let callback of this.afterSaveEntityCallbacks) {
397
574
  if (callback) {
398
575
  await callback(this, result);
@@ -411,8 +588,10 @@ export default class Nymph {
411
588
  * - offset - The offset from the oldest matching entity to start retrieving.
412
589
  * - reverse - If true, entities will be retrieved from newest to oldest.
413
590
  * Therefore, offset will be from the newest entity.
414
- * - sort - How to sort the entities. Accepts "cdate" or "mdate". Defaults to
415
- * "cdate".
591
+ * - sort - How to sort the entities. Accepts "cdate", "mdate", or the name of
592
+ * a top-level property. The method of sorting properties other than cdate
593
+ * and mdate is driver dependent. The only hard rule is that numbers should
594
+ * be sorted numerically (2 before 10). Defaults to "cdate".
416
595
  * - return - What to return. "entity", "guid", or "count". Defaults to
417
596
  * "entity".
418
597
  * - source - Will be 'client' if the query came from a REST call.
@@ -656,7 +835,17 @@ export default class Nymph {
656
835
  await callback(this, entity);
657
836
  }
658
837
  }
659
- const result = this.driver.deleteEntity(entity);
838
+ let result: Promise<boolean>;
839
+ try {
840
+ result = this.driver.deleteEntity(entity);
841
+ } catch (e: any) {
842
+ for (let callback of this.failedDeleteEntityCallbacks) {
843
+ if (callback) {
844
+ await callback(this, e);
845
+ }
846
+ }
847
+ throw e;
848
+ }
660
849
  for (let callback of this.afterDeleteEntityCallbacks) {
661
850
  if (callback) {
662
851
  await callback(this, result);
@@ -681,7 +870,17 @@ export default class Nymph {
681
870
  await callback(this, guid, className);
682
871
  }
683
872
  }
684
- const result = this.driver.deleteEntityByID(guid, className);
873
+ let result: Promise<boolean>;
874
+ try {
875
+ result = this.driver.deleteEntityByID(guid, className);
876
+ } catch (e: any) {
877
+ for (let callback of this.failedDeleteEntityByIDCallbacks) {
878
+ if (callback) {
879
+ await callback(this, e);
880
+ }
881
+ }
882
+ throw e;
883
+ }
685
884
  for (let callback of this.afterDeleteEntityByIDCallbacks) {
686
885
  if (callback) {
687
886
  await callback(this, result);
@@ -712,7 +911,7 @@ export default class Nymph {
712
911
  * # brackets ([]).
713
912
  * # Properties are stored like this:
714
913
  * # propname=JSON.stringify(value)
715
- * abilities=["system/all"]
914
+ * abilities=["system/admin"]
716
915
  * groups=[]
717
916
  * inheritAbilities=false
718
917
  * name="admin"
@@ -765,30 +964,56 @@ export default class Nymph {
765
964
  ? NymphBeforeSaveEntityCallback
766
965
  : T extends 'afterSaveEntity'
767
966
  ? NymphAfterSaveEntityCallback
967
+ : T extends 'failedSaveEntity'
968
+ ? NymphFailedSaveEntityCallback
768
969
  : T extends 'beforeDeleteEntity'
769
970
  ? NymphBeforeDeleteEntityCallback
770
971
  : T extends 'afterDeleteEntity'
771
972
  ? NymphAfterDeleteEntityCallback
973
+ : T extends 'failedDeleteEntity'
974
+ ? NymphFailedDeleteEntityCallback
772
975
  : T extends 'beforeDeleteEntityByID'
773
976
  ? NymphBeforeDeleteEntityByIDCallback
774
977
  : T extends 'afterDeleteEntityByID'
775
978
  ? NymphAfterDeleteEntityByIDCallback
979
+ : T extends 'failedDeleteEntityByID'
980
+ ? NymphFailedDeleteEntityByIDCallback
776
981
  : T extends 'beforeNewUID'
777
982
  ? NymphBeforeNewUIDCallback
778
983
  : T extends 'afterNewUID'
779
984
  ? NymphAfterNewUIDCallback
985
+ : T extends 'failedNewUID'
986
+ ? NymphFailedNewUIDCallback
780
987
  : T extends 'beforeSetUID'
781
988
  ? NymphBeforeSetUIDCallback
782
989
  : T extends 'afterSetUID'
783
990
  ? NymphAfterSetUIDCallback
991
+ : T extends 'failedSetUID'
992
+ ? NymphFailedSetUIDCallback
784
993
  : T extends 'beforeRenameUID'
785
994
  ? NymphBeforeRenameUIDCallback
786
995
  : T extends 'afterRenameUID'
787
996
  ? NymphAfterRenameUIDCallback
997
+ : T extends 'failedRenameUID'
998
+ ? NymphFailedRenameUIDCallback
788
999
  : T extends 'beforeDeleteUID'
789
1000
  ? NymphBeforeDeleteUIDCallback
790
1001
  : T extends 'afterDeleteUID'
791
1002
  ? NymphAfterDeleteUIDCallback
1003
+ : T extends 'failedDeleteUID'
1004
+ ? NymphFailedDeleteUIDCallback
1005
+ : T extends 'beforeStartTransaction'
1006
+ ? NymphBeforeStartTransactionCallback
1007
+ : T extends 'afterStartTransaction'
1008
+ ? NymphAfterStartTransactionCallback
1009
+ : T extends 'beforeCommitTransaction'
1010
+ ? NymphBeforeCommitTransactionCallback
1011
+ : T extends 'afterCommitTransaction'
1012
+ ? NymphAfterCommitTransactionCallback
1013
+ : T extends 'beforeRollbackTransaction'
1014
+ ? NymphBeforeRollbackTransactionCallback
1015
+ : T extends 'afterRollbackTransaction'
1016
+ ? NymphAfterRollbackTransactionCallback
792
1017
  : never
793
1018
  ) {
794
1019
  const prop = (event + 'Callbacks') as T extends 'connect'
@@ -805,30 +1030,56 @@ export default class Nymph {
805
1030
  ? 'beforeSaveEntityCallbacks'
806
1031
  : T extends 'afterSaveEntity'
807
1032
  ? 'afterSaveEntityCallbacks'
1033
+ : T extends 'failedSaveEntity'
1034
+ ? 'failedSaveEntityCallbacks'
808
1035
  : T extends 'beforeDeleteEntity'
809
1036
  ? 'beforeDeleteEntityCallbacks'
810
1037
  : T extends 'afterDeleteEntity'
811
1038
  ? 'afterDeleteEntityCallbacks'
1039
+ : T extends 'failedDeleteEntity'
1040
+ ? 'failedDeleteEntityCallbacks'
812
1041
  : T extends 'beforeDeleteEntityByID'
813
1042
  ? 'beforeDeleteEntityByIDCallbacks'
814
1043
  : T extends 'afterDeleteEntityByID'
815
1044
  ? 'afterDeleteEntityByIDCallbacks'
1045
+ : T extends 'failedDeleteEntityByID'
1046
+ ? 'failedDeleteEntityByIDCallbacks'
816
1047
  : T extends 'beforeNewUID'
817
1048
  ? 'beforeNewUIDCallbacks'
818
1049
  : T extends 'afterNewUID'
819
1050
  ? 'afterNewUIDCallbacks'
1051
+ : T extends 'failedNewUID'
1052
+ ? 'failedNewUIDCallbacks'
820
1053
  : T extends 'beforeSetUID'
821
1054
  ? 'beforeSetUIDCallbacks'
822
1055
  : T extends 'afterSetUID'
823
1056
  ? 'afterSetUIDCallbacks'
1057
+ : T extends 'failedSetUID'
1058
+ ? 'failedSetUIDCallbacks'
824
1059
  : T extends 'beforeRenameUID'
825
1060
  ? 'beforeRenameUIDCallbacks'
826
1061
  : T extends 'afterRenameUID'
827
1062
  ? 'afterRenameUIDCallbacks'
1063
+ : T extends 'failedRenameUID'
1064
+ ? 'failedRenameUIDCallbacks'
828
1065
  : T extends 'beforeDeleteUID'
829
1066
  ? 'beforeDeleteUIDCallbacks'
830
1067
  : T extends 'afterDeleteUID'
831
1068
  ? 'afterDeleteUIDCallbacks'
1069
+ : T extends 'failedDeleteUID'
1070
+ ? 'failedDeleteUIDCallbacks'
1071
+ : T extends 'beforeStartTransaction'
1072
+ ? 'beforeStartTransactionCallbacks'
1073
+ : T extends 'afterStartTransaction'
1074
+ ? 'afterStartTransactionCallbacks'
1075
+ : T extends 'beforeCommitTransaction'
1076
+ ? 'beforeCommitTransactionCallbacks'
1077
+ : T extends 'afterCommitTransaction'
1078
+ ? 'afterCommitTransactionCallbacks'
1079
+ : T extends 'beforeRollbackTransaction'
1080
+ ? 'beforeRollbackTransactionCallbacks'
1081
+ : T extends 'afterRollbackTransaction'
1082
+ ? 'afterRollbackTransactionCallbacks'
832
1083
  : never;
833
1084
  if (!(prop in this)) {
834
1085
  throw new Error('Invalid event type.');
@@ -854,30 +1105,56 @@ export default class Nymph {
854
1105
  ? NymphBeforeSaveEntityCallback
855
1106
  : T extends 'afterSaveEntity'
856
1107
  ? NymphAfterSaveEntityCallback
1108
+ : T extends 'failedSaveEntity'
1109
+ ? NymphFailedSaveEntityCallback
857
1110
  : T extends 'beforeDeleteEntity'
858
1111
  ? NymphBeforeDeleteEntityCallback
859
1112
  : T extends 'afterDeleteEntity'
860
1113
  ? NymphAfterDeleteEntityCallback
1114
+ : T extends 'failedDeleteEntity'
1115
+ ? NymphFailedDeleteEntityCallback
861
1116
  : T extends 'beforeDeleteEntityByID'
862
1117
  ? NymphBeforeDeleteEntityByIDCallback
863
1118
  : T extends 'afterDeleteEntityByID'
864
1119
  ? NymphAfterDeleteEntityByIDCallback
1120
+ : T extends 'failedDeleteEntityByID'
1121
+ ? NymphFailedDeleteEntityByIDCallback
865
1122
  : T extends 'beforeNewUID'
866
1123
  ? NymphBeforeNewUIDCallback
867
1124
  : T extends 'afterNewUID'
868
1125
  ? NymphAfterNewUIDCallback
1126
+ : T extends 'failedNewUID'
1127
+ ? NymphFailedNewUIDCallback
869
1128
  : T extends 'beforeSetUID'
870
1129
  ? NymphBeforeSetUIDCallback
871
1130
  : T extends 'afterSetUID'
872
1131
  ? NymphAfterSetUIDCallback
1132
+ : T extends 'failedSetUID'
1133
+ ? NymphFailedSetUIDCallback
873
1134
  : T extends 'beforeRenameUID'
874
1135
  ? NymphBeforeRenameUIDCallback
875
1136
  : T extends 'afterRenameUID'
876
1137
  ? NymphAfterRenameUIDCallback
1138
+ : T extends 'failedRenameUID'
1139
+ ? NymphFailedRenameUIDCallback
877
1140
  : T extends 'beforeDeleteUID'
878
1141
  ? NymphBeforeDeleteUIDCallback
879
1142
  : T extends 'afterDeleteUID'
880
1143
  ? NymphAfterDeleteUIDCallback
1144
+ : T extends 'failedDeleteUID'
1145
+ ? NymphFailedDeleteUIDCallback
1146
+ : T extends 'beforeStartTransaction'
1147
+ ? NymphBeforeStartTransactionCallback
1148
+ : T extends 'afterStartTransaction'
1149
+ ? NymphAfterStartTransactionCallback
1150
+ : T extends 'beforeCommitTransaction'
1151
+ ? NymphBeforeCommitTransactionCallback
1152
+ : T extends 'afterCommitTransaction'
1153
+ ? NymphAfterCommitTransactionCallback
1154
+ : T extends 'beforeRollbackTransaction'
1155
+ ? NymphBeforeRollbackTransactionCallback
1156
+ : T extends 'afterRollbackTransaction'
1157
+ ? NymphAfterRollbackTransactionCallback
881
1158
  : never
882
1159
  ) {
883
1160
  const prop = (event + 'Callbacks') as T extends 'connect'
@@ -894,30 +1171,56 @@ export default class Nymph {
894
1171
  ? 'beforeGetEntitiesCallbacks'
895
1172
  : T extends 'afterSaveEntity'
896
1173
  ? 'afterSaveEntityCallbacks'
1174
+ : T extends 'failedSaveEntity'
1175
+ ? 'failedSaveEntityCallbacks'
897
1176
  : T extends 'beforeDeleteEntity'
898
1177
  ? 'beforeDeleteEntityCallbacks'
899
1178
  : T extends 'afterDeleteEntity'
900
1179
  ? 'afterDeleteEntityCallbacks'
1180
+ : T extends 'failedDeleteEntity'
1181
+ ? 'failedDeleteEntityCallbacks'
901
1182
  : T extends 'beforeDeleteEntityByID'
902
1183
  ? 'beforeDeleteEntityByIDCallbacks'
903
1184
  : T extends 'afterDeleteEntityByID'
904
1185
  ? 'afterDeleteEntityByIDCallbacks'
1186
+ : T extends 'failedDeleteEntityByID'
1187
+ ? 'failedDeleteEntityByIDCallbacks'
905
1188
  : T extends 'beforeNewUID'
906
1189
  ? 'beforeNewUIDCallbacks'
907
1190
  : T extends 'afterNewUID'
908
1191
  ? 'afterNewUIDCallbacks'
1192
+ : T extends 'failedNewUID'
1193
+ ? 'failedNewUIDCallbacks'
909
1194
  : T extends 'beforeSetUID'
910
1195
  ? 'beforeSetUIDCallbacks'
911
1196
  : T extends 'afterSetUID'
912
1197
  ? 'afterSetUIDCallbacks'
1198
+ : T extends 'failedSetUID'
1199
+ ? 'failedSetUIDCallbacks'
913
1200
  : T extends 'beforeRenameUID'
914
1201
  ? 'beforeRenameUIDCallbacks'
915
1202
  : T extends 'afterRenameUID'
916
1203
  ? 'afterRenameUIDCallbacks'
1204
+ : T extends 'failedRenameUID'
1205
+ ? 'failedRenameUIDCallbacks'
917
1206
  : T extends 'beforeDeleteUID'
918
1207
  ? 'beforeDeleteUIDCallbacks'
919
1208
  : T extends 'afterDeleteUID'
920
1209
  ? 'afterDeleteUIDCallbacks'
1210
+ : T extends 'failedDeleteUID'
1211
+ ? 'failedDeleteUIDCallbacks'
1212
+ : T extends 'beforeStartTransaction'
1213
+ ? 'beforeStartTransactionCallbacks'
1214
+ : T extends 'afterStartTransaction'
1215
+ ? 'afterStartTransactionCallbacks'
1216
+ : T extends 'beforeCommitTransaction'
1217
+ ? 'beforeCommitTransactionCallbacks'
1218
+ : T extends 'afterCommitTransaction'
1219
+ ? 'afterCommitTransactionCallbacks'
1220
+ : T extends 'beforeRollbackTransaction'
1221
+ ? 'beforeRollbackTransactionCallbacks'
1222
+ : T extends 'afterRollbackTransaction'
1223
+ ? 'afterRollbackTransactionCallbacks'
921
1224
  : never;
922
1225
  if (!(prop in this)) {
923
1226
  return false;