@nymphjs/nymph 1.0.0-beta.13 → 1.0.0-beta.131

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 (123) hide show
  1. package/CHANGELOG.md +650 -0
  2. package/README.md +34 -24
  3. package/dist/Entity.d.ts +306 -15
  4. package/dist/Entity.js +688 -226
  5. package/dist/Entity.js.map +1 -1
  6. package/dist/Entity.test.js +75 -29
  7. package/dist/Entity.test.js.map +1 -1
  8. package/dist/Entity.types.d.ts +275 -28
  9. package/dist/Entity.types.js +1 -2
  10. package/dist/Nymph.d.ts +575 -11
  11. package/dist/Nymph.js +825 -288
  12. package/dist/Nymph.js.map +1 -1
  13. package/dist/Nymph.types.d.ts +117 -7
  14. package/dist/Nymph.types.js +47 -5
  15. package/dist/Nymph.types.js.map +1 -1
  16. package/dist/conf/defaults.d.ts +1 -1
  17. package/dist/conf/defaults.js +26 -3
  18. package/dist/conf/defaults.js.map +1 -1
  19. package/dist/conf/index.d.ts +50 -2
  20. package/dist/conf/index.js +2 -8
  21. package/dist/conf/index.js.map +1 -1
  22. package/dist/decorators/index.d.ts +1 -0
  23. package/dist/decorators/index.js +2 -0
  24. package/dist/decorators/index.js.map +1 -0
  25. package/dist/decorators/transactional.d.ts +12 -0
  26. package/dist/decorators/transactional.js +45 -0
  27. package/dist/decorators/transactional.js.map +1 -0
  28. package/dist/driver/NymphDriver.d.ts +209 -41
  29. package/dist/driver/NymphDriver.js +737 -242
  30. package/dist/driver/NymphDriver.js.map +1 -1
  31. package/dist/driver/index.d.ts +1 -2
  32. package/dist/driver/index.js +2 -23
  33. package/dist/driver/index.js.map +1 -1
  34. package/dist/driver/testArtifacts.d.ts +4 -4
  35. package/dist/driver/testArtifacts.js +2016 -1086
  36. package/dist/driver/testArtifacts.js.map +1 -1
  37. package/dist/errors/ClassNotAvailableError.js +1 -5
  38. package/dist/errors/ClassNotAvailableError.js.map +1 -1
  39. package/dist/errors/EntityConflictError.js +1 -5
  40. package/dist/errors/EntityConflictError.js.map +1 -1
  41. package/dist/errors/EntityInvalidDataError.d.ts +6 -0
  42. package/dist/errors/EntityInvalidDataError.js +8 -6
  43. package/dist/errors/EntityInvalidDataError.js.map +1 -1
  44. package/dist/errors/EntityIsSleepingReferenceError.js +1 -5
  45. package/dist/errors/EntityIsSleepingReferenceError.js.map +1 -1
  46. package/dist/errors/EntityUniqueConstraintError.d.ts +3 -0
  47. package/dist/errors/EntityUniqueConstraintError.js +7 -0
  48. package/dist/errors/EntityUniqueConstraintError.js.map +1 -0
  49. package/dist/errors/HttpError.d.ts +5 -0
  50. package/dist/errors/HttpError.js +11 -0
  51. package/dist/errors/HttpError.js.map +1 -0
  52. package/dist/errors/InvalidParametersError.js +1 -5
  53. package/dist/errors/InvalidParametersError.js.map +1 -1
  54. package/dist/errors/InvalidStateError.d.ts +3 -0
  55. package/dist/errors/InvalidStateError.js +7 -0
  56. package/dist/errors/InvalidStateError.js.map +1 -0
  57. package/dist/errors/MethodFailedError.d.ts +3 -0
  58. package/dist/errors/MethodFailedError.js +7 -0
  59. package/dist/errors/MethodFailedError.js.map +1 -0
  60. package/dist/errors/NotConfiguredError.js +1 -5
  61. package/dist/errors/NotConfiguredError.js.map +1 -1
  62. package/dist/errors/QueryFailedError.d.ts +2 -1
  63. package/dist/errors/QueryFailedError.js +5 -6
  64. package/dist/errors/QueryFailedError.js.map +1 -1
  65. package/dist/errors/UnableToConnectError.js +1 -5
  66. package/dist/errors/UnableToConnectError.js.map +1 -1
  67. package/dist/errors/index.d.ts +12 -8
  68. package/dist/errors/index.js +12 -24
  69. package/dist/errors/index.js.map +1 -1
  70. package/dist/helpers/index.d.ts +1 -0
  71. package/dist/helpers/index.js +2 -0
  72. package/dist/helpers/index.js.map +1 -0
  73. package/dist/helpers/transaction.d.ts +15 -0
  74. package/dist/helpers/transaction.js +47 -0
  75. package/dist/helpers/transaction.js.map +1 -0
  76. package/dist/index.d.ts +13 -11
  77. package/dist/index.js +16 -34
  78. package/dist/index.js.map +1 -1
  79. package/dist/nymphJoiProps.d.ts +1 -1
  80. package/dist/nymphJoiProps.js +10 -15
  81. package/dist/nymphJoiProps.js.map +1 -1
  82. package/dist/testArtifacts.d.ts +21 -6
  83. package/dist/testArtifacts.js +124 -50
  84. package/dist/testArtifacts.js.map +1 -1
  85. package/dist/testMocks.d.ts +27 -12
  86. package/dist/testMocks.js +44 -33
  87. package/dist/testMocks.js.map +1 -1
  88. package/dist/utils.d.ts +5 -5
  89. package/dist/utils.js +106 -68
  90. package/dist/utils.js.map +1 -1
  91. package/jest.config.js +31 -5
  92. package/package.json +43 -24
  93. package/src/Entity.test.ts +73 -23
  94. package/src/Entity.ts +646 -252
  95. package/src/Entity.types.ts +102 -90
  96. package/src/Nymph.ts +930 -517
  97. package/src/Nymph.types.ts +145 -39
  98. package/src/conf/defaults.ts +34 -1
  99. package/src/conf/index.ts +50 -2
  100. package/src/decorators/index.ts +1 -0
  101. package/src/decorators/transactional.ts +63 -0
  102. package/src/driver/NymphDriver.ts +987 -417
  103. package/src/driver/index.ts +1 -3
  104. package/src/driver/testArtifacts.ts +2699 -1628
  105. package/src/errors/EntityUniqueConstraintError.ts +6 -0
  106. package/src/errors/HttpError.ts +12 -0
  107. package/src/errors/InvalidStateError.ts +6 -0
  108. package/src/errors/MethodFailedError.ts +6 -0
  109. package/src/errors/QueryFailedError.ts +3 -1
  110. package/src/errors/index.ts +16 -8
  111. package/src/helpers/index.ts +1 -0
  112. package/src/helpers/transaction.ts +65 -0
  113. package/src/index.ts +13 -11
  114. package/src/nymphJoiProps.ts +2 -2
  115. package/src/testArtifacts.ts +69 -20
  116. package/src/testMocks.ts +107 -41
  117. package/src/utils.ts +102 -67
  118. package/tsconfig.json +6 -3
  119. package/typedoc.json +4 -0
  120. package/dist/conf/d.d.ts +0 -6
  121. package/dist/conf/d.js +0 -3
  122. package/dist/conf/d.js.map +0 -1
  123. package/src/conf/d.ts +0 -24
package/src/Nymph.ts CHANGED
@@ -1,8 +1,18 @@
1
- import { Config, ConfigDefaults as defaults } from './conf';
2
- import { NymphDriver } from './driver';
3
- import Entity from './Entity';
4
- import { EntityConstructor, EntityInterface } from './Entity.types';
5
- import { ClassNotAvailableError } from './errors';
1
+ import { Config, ConfigDefaults as defaults } from './conf/index.js';
2
+ import type { NymphDriver } from './driver/index.js';
3
+ import Entity, {
4
+ type EntityInstanceType,
5
+ type EntityObjectType,
6
+ } from './Entity.js';
7
+ import type {
8
+ EntityConstructor,
9
+ EntityInterface,
10
+ SerializedEntityData,
11
+ } from './Entity.types.js';
12
+ import {
13
+ ClassNotAvailableError,
14
+ InvalidParametersError,
15
+ } from './errors/index.js';
6
16
  import type {
7
17
  Selector,
8
18
  Options,
@@ -41,14 +51,14 @@ import type {
41
51
  NymphQueryCallback,
42
52
  FormattedSelector,
43
53
  TilmeldInterface,
44
- } from './Nymph.types';
54
+ } from './Nymph.types.js';
45
55
 
46
56
  /**
47
57
  * An object relational mapper for Node.js.
48
58
  *
49
59
  * Written by Hunter Perrin for SciActive.
50
60
  *
51
- * @author Hunter Perrin <hperrin@gmail.com>
61
+ * @author Hunter Perrin <hperrin@port87.com>
52
62
  * @copyright SciActive Inc
53
63
  * @see http://nymph.io/
54
64
  */
@@ -132,25 +142,90 @@ export default class Nymph {
132
142
  * @param config The Nymph configuration.
133
143
  * @param driver The Nymph database driver.
134
144
  * @param tilmeld The Tilmeld user/group manager instance, if you want to use it.
145
+ * @param parent Used internally by Nymph. Don't set this.
135
146
  */
136
147
  public constructor(
137
148
  config: Partial<Config>,
138
149
  driver: NymphDriver,
139
- tilmeld?: TilmeldInterface
150
+ tilmeld?: TilmeldInterface,
151
+ parent?: Nymph,
140
152
  ) {
141
153
  this.config = { ...defaults, ...config };
142
154
  this.driver = driver;
143
- this.parent = null;
155
+ this.parent = parent ?? null;
144
156
 
145
157
  this.Entity = this.addEntityClass(Entity);
146
158
 
147
- if (typeof tilmeld !== 'undefined') {
159
+ if (parent) {
160
+ for (const name in parent.entityClasses) {
161
+ if (
162
+ name === 'Entity' ||
163
+ (parent.entityClasses[name] as any).skipOnClone
164
+ ) {
165
+ continue;
166
+ }
167
+ this.addEntityClass(parent.entityClasses[name]);
168
+ }
169
+
170
+ const events = [
171
+ 'connect',
172
+ 'disconnect',
173
+ 'query',
174
+ 'beforeGetEntity',
175
+ 'beforeGetEntities',
176
+ 'beforeSaveEntity',
177
+ 'afterSaveEntity',
178
+ 'failedSaveEntity',
179
+ 'beforeDeleteEntity',
180
+ 'afterDeleteEntity',
181
+ 'failedDeleteEntity',
182
+ 'beforeDeleteEntityByID',
183
+ 'afterDeleteEntityByID',
184
+ 'failedDeleteEntityByID',
185
+ 'beforeNewUID',
186
+ 'afterNewUID',
187
+ 'failedNewUID',
188
+ 'beforeSetUID',
189
+ 'afterSetUID',
190
+ 'failedSetUID',
191
+ 'beforeRenameUID',
192
+ 'afterRenameUID',
193
+ 'failedRenameUID',
194
+ 'beforeDeleteUID',
195
+ 'afterDeleteUID',
196
+ 'failedDeleteUID',
197
+ 'beforeStartTransaction',
198
+ 'afterStartTransaction',
199
+ 'beforeCommitTransaction',
200
+ 'afterCommitTransaction',
201
+ 'beforeRollbackTransaction',
202
+ 'afterRollbackTransaction',
203
+ ];
204
+
205
+ for (let event of events) {
206
+ const prop = event + 'Callbacks';
207
+ // @ts-ignore: The callback should be the right type here.
208
+ const callbacks = parent[prop];
209
+ for (let callback of callbacks) {
210
+ if (callback.skipOnClone) {
211
+ continue;
212
+ }
213
+ this.on(event as NymphEventType, callback);
214
+ }
215
+ }
216
+ }
217
+
218
+ this.config.debugInfo('nymph', 'Nymph loaded.');
219
+
220
+ if (tilmeld != null) {
148
221
  this.tilmeld = tilmeld;
149
222
  }
150
223
 
151
224
  this.driver.init(this);
225
+ this.config.debugInfo('nymph', 'Nymph driver loaded.');
152
226
  if (this.tilmeld) {
153
227
  this.tilmeld.init(this);
228
+ this.config.debugInfo('nymph', 'Tilmeld loaded.');
154
229
  }
155
230
  }
156
231
 
@@ -164,98 +239,93 @@ export default class Nymph {
164
239
  * Because this creates a subclass, don't use the class
165
240
  * returned from `getEntityClass` to check with `instanceof`.
166
241
  */
167
- public addEntityClass<T extends EntityConstructor>(entityClass: T): T {
242
+ public addEntityClass<T extends EntityConstructor>(EntityClass: T): T {
243
+ if (EntityClass.class in this.entityClasses) {
244
+ this.config.debugLog(
245
+ 'nymph',
246
+ `Adding duplicate class "${EntityClass.class}". This may be a mistake.`,
247
+ );
248
+ }
249
+
250
+ // Check that it doesn't have the same etype as any other class.
251
+ for (const ExistingClass of Object.values(this.entityClasses)) {
252
+ if (
253
+ EntityClass.ETYPE === ExistingClass.ETYPE &&
254
+ EntityClass.class !== EntityClass.class
255
+ ) {
256
+ this.config.debugLog(
257
+ 'nymph',
258
+ `Adding class "${EntityClass.class}" with same etype as existing class "${ExistingClass.class}". This may be a mistake.`,
259
+ );
260
+ }
261
+ }
262
+
168
263
  const nymph = this;
169
- class NymphEntity extends entityClass {
264
+ this.entityClasses[EntityClass.class] = class extends EntityClass {
170
265
  static nymph: Nymph = nymph;
171
266
 
172
267
  constructor(...args: any[]) {
173
268
  super(...args);
174
269
  }
175
- }
176
- this.entityClasses[entityClass.class] = NymphEntity;
177
- return NymphEntity;
270
+ };
271
+ return this.entityClasses[EntityClass.class] as T;
178
272
  }
179
273
 
180
274
  /**
181
275
  * Get the class that uses the specified class name.
182
276
  */
183
- public getEntityClass(className: string): EntityConstructor {
184
- if (className in this.entityClasses) {
185
- return this.entityClasses[className];
277
+ public getEntityClass(className: string): EntityConstructor;
278
+ public getEntityClass<T extends EntityConstructor>(className: T): T;
279
+ public getEntityClass<T extends EntityConstructor = EntityConstructor>(
280
+ className: T | string,
281
+ ): T | EntityConstructor {
282
+ let key: string | null = null;
283
+ if (typeof className === 'string') {
284
+ key = className;
285
+ } else {
286
+ key = className.class;
186
287
  }
187
- throw new ClassNotAvailableError('Tried to use class: ' + className);
288
+ if (key in this.entityClasses) {
289
+ return this.entityClasses[key];
290
+ }
291
+ this.config.debugError('nymph', `Tried to use missing class "${key}".`);
292
+ throw new ClassNotAvailableError(`Tried to use missing class "${key}".`);
188
293
  }
189
294
 
190
295
  /**
191
- * Get a clone of this instance with duplicate classes and event listeners.
296
+ * Get the class that uses the specified etype.
297
+ *
298
+ * Note that it is fine, though unusual, for two classes to use the same
299
+ * etype. However, this can lead to very hard to diagnose bugs, so is
300
+ * generally discouraged.
301
+ */
302
+ public getEntityClassByEtype(etype: string): EntityConstructor {
303
+ for (const EntityClass of Object.values(this.entityClasses)) {
304
+ if (EntityClass.ETYPE === etype) {
305
+ return EntityClass;
306
+ }
307
+ }
308
+ this.config.debugError(
309
+ 'nymph',
310
+ `Tried to use missing class by etype "${etype}".`,
311
+ );
312
+ throw new ClassNotAvailableError(
313
+ `Tried to use missing class by etype "${etype}".`,
314
+ );
315
+ }
316
+
317
+ /**
318
+ * Get a clone of this instance with cloned classes and event listeners.
192
319
  *
193
320
  * @returns A clone of this instance.
194
321
  */
195
322
  public clone() {
196
- const nymph = new Nymph(
323
+ return new Nymph(
197
324
  this.config,
198
325
  this.driver.clone(),
199
- this.tilmeld?.clone()
326
+ this.tilmeld?.clone(),
327
+ this,
200
328
  );
201
-
202
- nymph.parent = this;
203
-
204
- for (const name in this.entityClasses) {
205
- if (name === 'Entity' || (this.entityClasses[name] as any).skipOnClone) {
206
- continue;
207
- }
208
- nymph.addEntityClass(this.entityClasses[name]);
209
- }
210
-
211
- const events = [
212
- 'connect',
213
- 'disconnect',
214
- 'query',
215
- 'beforeGetEntity',
216
- 'beforeGetEntities',
217
- 'beforeSaveEntity',
218
- 'afterSaveEntity',
219
- 'failedSaveEntity',
220
- 'beforeDeleteEntity',
221
- 'afterDeleteEntity',
222
- 'failedDeleteEntity',
223
- 'beforeDeleteEntityByID',
224
- 'afterDeleteEntityByID',
225
- 'failedDeleteEntityByID',
226
- 'beforeNewUID',
227
- 'afterNewUID',
228
- 'failedNewUID',
229
- 'beforeSetUID',
230
- 'afterSetUID',
231
- 'failedSetUID',
232
- 'beforeRenameUID',
233
- 'afterRenameUID',
234
- 'failedRenameUID',
235
- 'beforeDeleteUID',
236
- 'afterDeleteUID',
237
- 'failedDeleteUID',
238
- 'beforeStartTransaction',
239
- 'afterStartTransaction',
240
- 'beforeCommitTransaction',
241
- 'afterCommitTransaction',
242
- 'beforeRollbackTransaction',
243
- 'afterRollbackTransaction',
244
- ];
245
-
246
- for (let event of events) {
247
- const prop = event + 'Callbacks';
248
- // @ts-ignore: The callback should be the right type here.
249
- const callbacks = this[prop];
250
- for (let callback of callbacks) {
251
- if (callback.skipOnClone) {
252
- continue;
253
- }
254
- nymph.on(event as NymphEventType, callback);
255
- }
256
- }
257
-
258
- return nymph;
259
329
  }
260
330
 
261
331
  /**
@@ -264,13 +334,19 @@ export default class Nymph {
264
334
  * @returns Whether the instance is connected to the database.
265
335
  */
266
336
  public async connect(): Promise<boolean> {
267
- const result = this.driver.connect();
268
- for (let callback of this.connectCallbacks) {
269
- if (callback) {
270
- await callback(this, result);
337
+ try {
338
+ const result = this.driver.connect();
339
+ for (let callback of this.connectCallbacks) {
340
+ if (callback) {
341
+ await callback(this, result);
342
+ }
271
343
  }
344
+ this.config.debugInfo('nymph', 'Driver connected.');
345
+ return await result;
346
+ } catch (e: any) {
347
+ this.config.debugError('nymph', `Failed to connect: ${e}`);
348
+ throw e;
272
349
  }
273
- return await result;
274
350
  }
275
351
 
276
352
  /**
@@ -279,13 +355,19 @@ export default class Nymph {
279
355
  * @returns Whether the instance is connected to the database.
280
356
  */
281
357
  public async disconnect(): Promise<boolean> {
282
- const result = this.driver.disconnect();
283
- for (let callback of this.disconnectCallbacks) {
284
- if (callback) {
285
- await callback(this, result);
358
+ try {
359
+ const result = this.driver.disconnect();
360
+ for (let callback of this.disconnectCallbacks) {
361
+ if (callback) {
362
+ await callback(this, result);
363
+ }
286
364
  }
365
+ this.config.debugInfo('nymph', 'Driver disconnected.');
366
+ return await result;
367
+ } catch (e: any) {
368
+ this.config.debugError('nymph', `Failed to disconnect: ${e}`);
369
+ throw e;
287
370
  }
288
- return await result;
289
371
  }
290
372
 
291
373
  /**
@@ -312,18 +394,24 @@ export default class Nymph {
312
394
  * @returns A new instance of Nymph that should be used for the transaction.
313
395
  */
314
396
  public async startTransaction(name: string): Promise<Nymph> {
315
- for (let callback of this.beforeStartTransactionCallbacks) {
316
- if (callback) {
317
- await callback(this, name);
397
+ try {
398
+ for (let callback of this.beforeStartTransactionCallbacks) {
399
+ if (callback) {
400
+ await callback(this, name);
401
+ }
318
402
  }
319
- }
320
- const result = await this.driver.startTransaction(name);
321
- for (let callback of this.afterStartTransactionCallbacks) {
322
- if (callback) {
323
- await callback(this, name, result);
403
+ this.config.debugLog('nymph', `Starting transaction "${name}".`);
404
+ const result = await this.driver.startTransaction(name);
405
+ for (let callback of this.afterStartTransactionCallbacks) {
406
+ if (callback) {
407
+ await callback(this, name, result);
408
+ }
324
409
  }
410
+ return result;
411
+ } catch (e: any) {
412
+ this.config.debugError('nymph', `Failed to start transaction: ${e}`);
413
+ throw e;
325
414
  }
326
- return result;
327
415
  }
328
416
 
329
417
  /**
@@ -334,18 +422,24 @@ export default class Nymph {
334
422
  * @returns True on success, false on failure.
335
423
  */
336
424
  public async commit(name: string): Promise<boolean> {
337
- for (let callback of this.beforeCommitTransactionCallbacks) {
338
- if (callback) {
339
- await callback(this, name);
425
+ try {
426
+ for (let callback of this.beforeCommitTransactionCallbacks) {
427
+ if (callback) {
428
+ await callback(this, name);
429
+ }
340
430
  }
341
- }
342
- const result = await this.driver.commit(name);
343
- for (let callback of this.afterCommitTransactionCallbacks) {
344
- if (callback) {
345
- await callback(this, name, result);
431
+ this.config.debugLog('nymph', `Committing transaction "${name}".`);
432
+ const result = await this.driver.commit(name);
433
+ for (let callback of this.afterCommitTransactionCallbacks) {
434
+ if (callback) {
435
+ await callback(this, name, result);
436
+ }
346
437
  }
438
+ return result;
439
+ } catch (e: any) {
440
+ this.config.debugError('nymph', `Failed to commit transaction: ${e}`);
441
+ throw e;
347
442
  }
348
- return result;
349
443
  }
350
444
 
351
445
  /**
@@ -356,18 +450,24 @@ export default class Nymph {
356
450
  * @returns True on success, false on failure.
357
451
  */
358
452
  public async rollback(name: string): Promise<boolean> {
359
- for (let callback of this.beforeRollbackTransactionCallbacks) {
360
- if (callback) {
361
- await callback(this, name);
453
+ try {
454
+ for (let callback of this.beforeRollbackTransactionCallbacks) {
455
+ if (callback) {
456
+ await callback(this, name);
457
+ }
362
458
  }
363
- }
364
- const result = await this.driver.rollback(name);
365
- for (let callback of this.afterRollbackTransactionCallbacks) {
366
- if (callback) {
367
- await callback(this, name, result);
459
+ this.config.debugLog('nymph', `Rolling back transaction "${name}".`);
460
+ const result = await this.driver.rollback(name);
461
+ for (let callback of this.afterRollbackTransactionCallbacks) {
462
+ if (callback) {
463
+ await callback(this, name, result);
464
+ }
368
465
  }
466
+ return result;
467
+ } catch (e: any) {
468
+ this.config.debugError('nymph', `Failed to roll back transaction: ${e}`);
469
+ throw e;
369
470
  }
370
- return result;
371
471
  }
372
472
 
373
473
  /**
@@ -401,28 +501,33 @@ export default class Nymph {
401
501
  * @returns The UID's new value, or null on failure.
402
502
  */
403
503
  public async newUID(name: string): Promise<number | null> {
404
- for (let callback of this.beforeNewUIDCallbacks) {
405
- if (callback) {
406
- await callback(this, name);
407
- }
408
- }
409
- let result: Promise<number | null>;
410
504
  try {
411
- result = this.driver.newUID(name);
412
- } catch (e: any) {
413
- for (let callback of this.failedNewUIDCallbacks) {
505
+ for (let callback of this.beforeNewUIDCallbacks) {
414
506
  if (callback) {
415
- await callback(this, e);
507
+ await callback(this, name);
416
508
  }
417
509
  }
418
- throw e;
419
- }
420
- for (let callback of this.afterNewUIDCallbacks) {
421
- if (callback) {
422
- await callback(this, result);
510
+ let result: Promise<number | null>;
511
+ try {
512
+ result = this.driver.newUID(name);
513
+ } catch (e: any) {
514
+ for (let callback of this.failedNewUIDCallbacks) {
515
+ if (callback) {
516
+ await callback(this, e);
517
+ }
518
+ }
519
+ throw e;
423
520
  }
521
+ for (let callback of this.afterNewUIDCallbacks) {
522
+ if (callback) {
523
+ await callback(this, result);
524
+ }
525
+ }
526
+ return await result;
527
+ } catch (e: any) {
528
+ this.config.debugError('nymph', `Failed to create UID "${name}": ${e}`);
529
+ throw e;
424
530
  }
425
- return await result;
426
531
  }
427
532
 
428
533
  /**
@@ -431,7 +536,12 @@ export default class Nymph {
431
536
  * @returns The UID's value, or null on failure and if it doesn't exist.
432
537
  */
433
538
  public async getUID(name: string): Promise<number | null> {
434
- return await this.driver.getUID(name);
539
+ try {
540
+ return await this.driver.getUID(name);
541
+ } catch (e: any) {
542
+ this.config.debugError('nymph', `Failed to get UID "${name}": ${e}`);
543
+ throw e;
544
+ }
435
545
  }
436
546
 
437
547
  /**
@@ -442,28 +552,33 @@ export default class Nymph {
442
552
  * @returns True on success, false on failure.
443
553
  */
444
554
  public async setUID(name: string, value: number): Promise<boolean> {
445
- for (let callback of this.beforeSetUIDCallbacks) {
446
- if (callback) {
447
- await callback(this, name, value);
448
- }
449
- }
450
- let result: Promise<boolean>;
451
555
  try {
452
- result = this.driver.setUID(name, value);
453
- } catch (e: any) {
454
- for (let callback of this.failedSetUIDCallbacks) {
556
+ for (let callback of this.beforeSetUIDCallbacks) {
455
557
  if (callback) {
456
- await callback(this, e);
558
+ await callback(this, name, value);
457
559
  }
458
560
  }
459
- throw e;
460
- }
461
- for (let callback of this.afterSetUIDCallbacks) {
462
- if (callback) {
463
- await callback(this, result);
561
+ let result: Promise<boolean>;
562
+ try {
563
+ result = this.driver.setUID(name, value);
564
+ } catch (e: any) {
565
+ for (let callback of this.failedSetUIDCallbacks) {
566
+ if (callback) {
567
+ await callback(this, e);
568
+ }
569
+ }
570
+ throw e;
464
571
  }
572
+ for (let callback of this.afterSetUIDCallbacks) {
573
+ if (callback) {
574
+ await callback(this, result);
575
+ }
576
+ }
577
+ return await result;
578
+ } catch (e: any) {
579
+ this.config.debugError('nymph', `Failed to set UID "${name}": ${e}`);
580
+ throw e;
465
581
  }
466
- return await result;
467
582
  }
468
583
 
469
584
  /**
@@ -473,28 +588,33 @@ export default class Nymph {
473
588
  * @returns True on success, false on failure.
474
589
  */
475
590
  public async deleteUID(name: string): Promise<boolean> {
476
- for (let callback of this.beforeDeleteUIDCallbacks) {
477
- if (callback) {
478
- await callback(this, name);
479
- }
480
- }
481
- let result: Promise<boolean>;
482
591
  try {
483
- result = this.driver.deleteUID(name);
484
- } catch (e: any) {
485
- for (let callback of this.failedDeleteUIDCallbacks) {
592
+ for (let callback of this.beforeDeleteUIDCallbacks) {
486
593
  if (callback) {
487
- await callback(this, e);
594
+ await callback(this, name);
488
595
  }
489
596
  }
490
- throw e;
491
- }
492
- for (let callback of this.afterDeleteUIDCallbacks) {
493
- if (callback) {
494
- await callback(this, result);
597
+ let result: Promise<boolean>;
598
+ try {
599
+ result = this.driver.deleteUID(name);
600
+ } catch (e: any) {
601
+ for (let callback of this.failedDeleteUIDCallbacks) {
602
+ if (callback) {
603
+ await callback(this, e);
604
+ }
605
+ }
606
+ throw e;
607
+ }
608
+ for (let callback of this.afterDeleteUIDCallbacks) {
609
+ if (callback) {
610
+ await callback(this, result);
611
+ }
495
612
  }
613
+ return await result;
614
+ } catch (e: any) {
615
+ this.config.debugError('nymph', `Failed to delete UID "${name}": ${e}`);
616
+ throw e;
496
617
  }
497
- return await result;
498
618
  }
499
619
 
500
620
  /**
@@ -505,28 +625,36 @@ export default class Nymph {
505
625
  * @returns True on success, false on failure.
506
626
  */
507
627
  public async renameUID(oldName: string, newName: string): Promise<boolean> {
508
- for (let callback of this.beforeRenameUIDCallbacks) {
509
- if (callback) {
510
- await callback(this, oldName, newName);
511
- }
512
- }
513
- let result: Promise<boolean>;
514
628
  try {
515
- result = this.driver.renameUID(oldName, newName);
516
- } catch (e: any) {
517
- for (let callback of this.failedRenameUIDCallbacks) {
629
+ for (let callback of this.beforeRenameUIDCallbacks) {
518
630
  if (callback) {
519
- await callback(this, e);
631
+ await callback(this, oldName, newName);
520
632
  }
521
633
  }
522
- throw e;
523
- }
524
- for (let callback of this.afterRenameUIDCallbacks) {
525
- if (callback) {
526
- await callback(this, result);
634
+ let result: Promise<boolean>;
635
+ try {
636
+ result = this.driver.renameUID(oldName, newName);
637
+ } catch (e: any) {
638
+ for (let callback of this.failedRenameUIDCallbacks) {
639
+ if (callback) {
640
+ await callback(this, e);
641
+ }
642
+ }
643
+ throw e;
527
644
  }
645
+ for (let callback of this.afterRenameUIDCallbacks) {
646
+ if (callback) {
647
+ await callback(this, result);
648
+ }
649
+ }
650
+ return await result;
651
+ } catch (e: any) {
652
+ this.config.debugError(
653
+ 'nymph',
654
+ `Failed to rename UID "${oldName}" to "${newName}": ${e}`,
655
+ );
656
+ throw e;
528
657
  }
529
- return await result;
530
658
  }
531
659
 
532
660
  /**
@@ -541,28 +669,33 @@ export default class Nymph {
541
669
  * @returns True on success, false on failure.
542
670
  */
543
671
  public async saveEntity(entity: EntityInterface): Promise<boolean> {
544
- for (let callback of this.beforeSaveEntityCallbacks) {
545
- if (callback) {
546
- await callback(this, entity);
547
- }
548
- }
549
- let result: Promise<boolean>;
550
672
  try {
551
- result = this.driver.saveEntity(entity);
552
- } catch (e: any) {
553
- for (let callback of this.failedSaveEntityCallbacks) {
673
+ for (let callback of this.beforeSaveEntityCallbacks) {
554
674
  if (callback) {
555
- await callback(this, e);
675
+ await callback(this, entity);
556
676
  }
557
677
  }
558
- throw e;
559
- }
560
- for (let callback of this.afterSaveEntityCallbacks) {
561
- if (callback) {
562
- await callback(this, result);
678
+ let result: Promise<boolean>;
679
+ try {
680
+ result = this.driver.saveEntity(entity);
681
+ } catch (e: any) {
682
+ for (let callback of this.failedSaveEntityCallbacks) {
683
+ if (callback) {
684
+ await callback(this, e);
685
+ }
686
+ }
687
+ throw e;
563
688
  }
689
+ for (let callback of this.afterSaveEntityCallbacks) {
690
+ if (callback) {
691
+ await callback(this, result);
692
+ }
693
+ }
694
+ return await result;
695
+ } catch (e: any) {
696
+ this.config.debugError('nymph', `Failed to save entity: ${e}`);
697
+ throw e;
564
698
  }
565
- return await result;
566
699
  }
567
700
 
568
701
  /**
@@ -575,10 +708,13 @@ export default class Nymph {
575
708
  * - offset - The offset from the oldest matching entity to start retrieving.
576
709
  * - reverse - If true, entities will be retrieved from newest to oldest.
577
710
  * Therefore, offset will be from the newest entity.
578
- * - sort - How to sort the entities. Accepts "cdate" or "mdate". Defaults to
579
- * "cdate".
580
- * - return - What to return. "entity", "guid", or "count". Defaults to
581
- * "entity".
711
+ * - sort - How to sort the entities. Accepts "cdate", "mdate", the name of a
712
+ * top-level property, or null for no particular order. The method of
713
+ * sorting properties other than cdate and mdate is driver dependent. The
714
+ * only hard rule is that numbers should be sorted numerically (2 before
715
+ * 10). Defaults to "cdate".
716
+ * - return - What to return. "entity", "object", "guid", or "count". Defaults
717
+ * to "entity".
582
718
  * - source - Will be 'client' if the query came from a REST call.
583
719
  * - skipCache - If true, Nymph will skip the cache and retrieve the entity
584
720
  * from the DB.
@@ -611,6 +747,11 @@ export default class Nymph {
611
747
  * - contain - An array with a name, then value. True if the named property
612
748
  * contains the value (its JSON string is found within the property's JSON
613
749
  * string).
750
+ * - search - An array with a name, then search query. True if the named
751
+ * property matches the query. Use single quotes to find sequential terms.
752
+ * Use double quotes to find exact terms. Use "or" as the or operator. Use
753
+ * "-" before a term as the negation operator. Stop words and punctuation
754
+ * are stripped. Case insensitive.
614
755
  * - match - An array with a name, then regular expression. True if the
615
756
  * named property matches. Uses POSIX RegExp. Case sensitive. Must *not* be
616
757
  * surrounded by any delimiters.
@@ -732,20 +873,37 @@ export default class Nymph {
732
873
  options: Options<T> & { return: 'guid' },
733
874
  ...selectors: Selector[]
734
875
  ): Promise<string[]>;
876
+ public async getEntities<T extends EntityConstructor = EntityConstructor>(
877
+ options: Options<T> & { return: 'object' },
878
+ ...selectors: Selector[]
879
+ ): Promise<EntityObjectType<T>[]>;
735
880
  public async getEntities<T extends EntityConstructor = EntityConstructor>(
736
881
  options?: Options<T>,
737
882
  ...selectors: Selector[]
738
- ): Promise<ReturnType<T['factorySync']>[]>;
883
+ ): Promise<EntityInstanceType<T>[]>;
739
884
  public async getEntities<T extends EntityConstructor = EntityConstructor>(
740
885
  options: Options<T> = {},
741
886
  ...selectors: Selector[]
742
- ): Promise<ReturnType<T['factorySync']>[] | string[] | number> {
743
- for (let callback of this.beforeGetEntitiesCallbacks) {
744
- if (callback) {
745
- await callback(this, options, selectors);
887
+ ): Promise<
888
+ EntityInstanceType<T>[] | EntityObjectType<T>[] | string[] | number
889
+ > {
890
+ if (options.source === 'client' && options.return === 'object') {
891
+ throw new InvalidParametersError(
892
+ 'Object return type not allowed from client.',
893
+ );
894
+ }
895
+
896
+ try {
897
+ for (let callback of this.beforeGetEntitiesCallbacks) {
898
+ if (callback) {
899
+ await callback(this, options, selectors);
900
+ }
746
901
  }
902
+ return await this.driver.getEntities(options, ...selectors);
903
+ } catch (e: any) {
904
+ this.config.debugError('nymph', `Failed to get entities: ${e}`);
905
+ throw e;
747
906
  }
748
- return await this.driver.getEntities(options, ...selectors);
749
907
  }
750
908
 
751
909
  /**
@@ -769,43 +927,64 @@ export default class Nymph {
769
927
  options: Options<T> & { return: 'guid' },
770
928
  ...selectors: Selector[]
771
929
  ): Promise<string | null>;
930
+ public async getEntity<T extends EntityConstructor = EntityConstructor>(
931
+ options: Options<T> & { return: 'object' },
932
+ ...selectors: Selector[]
933
+ ): Promise<EntityObjectType<T> | null>;
772
934
  public async getEntity<T extends EntityConstructor = EntityConstructor>(
773
935
  options: Options<T>,
774
936
  ...selectors: Selector[]
775
- ): Promise<ReturnType<T['factorySync']> | null>;
937
+ ): Promise<EntityInstanceType<T> | null>;
776
938
  public async getEntity<T extends EntityConstructor = EntityConstructor>(
777
939
  options: Options<T> & { return: 'guid' },
778
- guid: string
940
+ guid: string,
779
941
  ): Promise<string | null>;
942
+ public async getEntity<T extends EntityConstructor = EntityConstructor>(
943
+ options: Options<T> & { return: 'object' },
944
+ guid: string,
945
+ ): Promise<EntityObjectType<T> | null>;
780
946
  public async getEntity<T extends EntityConstructor = EntityConstructor>(
781
947
  options: Options<T>,
782
- guid: string
783
- ): Promise<ReturnType<T['factorySync']> | null>;
948
+ guid: string,
949
+ ): Promise<EntityInstanceType<T> | null>;
784
950
  public async getEntity<T extends EntityConstructor = EntityConstructor>(
785
951
  options: Options<T> = {},
786
952
  ...selectors: Selector[] | string[]
787
- ): Promise<ReturnType<T['factorySync']> | string | number | null> {
788
- // Set up options and selectors.
789
- if (typeof selectors[0] === 'string') {
790
- selectors = [{ type: '&', guid: selectors[0] }];
953
+ ): Promise<
954
+ EntityInstanceType<T> | EntityObjectType<T> | string | number | null
955
+ > {
956
+ if (options.source === 'client' && options.return === 'object') {
957
+ throw new InvalidParametersError(
958
+ 'Object return type not allowed from client.',
959
+ );
791
960
  }
792
- options.limit = 1;
793
- for (let callback of this.beforeGetEntityCallbacks) {
794
- if (callback) {
795
- await callback(this, options, selectors as Selector[]);
961
+
962
+ try {
963
+ // Set up options and selectors.
964
+ if (typeof selectors[0] === 'string') {
965
+ selectors = [{ type: '&', guid: selectors[0] }];
796
966
  }
967
+ options.limit = 1;
968
+ for (let callback of this.beforeGetEntityCallbacks) {
969
+ if (callback) {
970
+ await callback(this, options, selectors as Selector[]);
971
+ }
972
+ }
973
+ const entities = await this.driver.getEntities(
974
+ options,
975
+ ...(selectors as Selector[]),
976
+ );
977
+ if (options.return === 'count') {
978
+ return entities as unknown as number;
979
+ }
980
+ if (!entities || !entities.length) {
981
+ return null;
982
+ }
983
+ return entities[0];
984
+ } catch (e: any) {
985
+ this.config.debugError('nymph', `Failed to get entity: ${e}`);
986
+ throw e;
797
987
  }
798
- const entities = await this.driver.getEntities(
799
- options,
800
- ...(selectors as Selector[])
801
- );
802
- if (options.return === 'count') {
803
- return entities as unknown as number;
804
- }
805
- if (!entities || !entities.length) {
806
- return null;
807
- }
808
- return entities[0];
809
988
  }
810
989
 
811
990
  /**
@@ -815,28 +994,33 @@ export default class Nymph {
815
994
  * @returns True on success, false on failure.
816
995
  */
817
996
  public async deleteEntity(entity: EntityInterface): Promise<boolean> {
818
- for (let callback of this.beforeDeleteEntityCallbacks) {
819
- if (callback) {
820
- await callback(this, entity);
821
- }
822
- }
823
- let result: Promise<boolean>;
824
997
  try {
825
- result = this.driver.deleteEntity(entity);
826
- } catch (e: any) {
827
- for (let callback of this.failedDeleteEntityCallbacks) {
998
+ for (let callback of this.beforeDeleteEntityCallbacks) {
828
999
  if (callback) {
829
- await callback(this, e);
1000
+ await callback(this, entity);
830
1001
  }
831
1002
  }
832
- throw e;
833
- }
834
- for (let callback of this.afterDeleteEntityCallbacks) {
835
- if (callback) {
836
- await callback(this, result);
1003
+ let result: Promise<boolean>;
1004
+ try {
1005
+ result = this.driver.deleteEntity(entity);
1006
+ } catch (e: any) {
1007
+ for (let callback of this.failedDeleteEntityCallbacks) {
1008
+ if (callback) {
1009
+ await callback(this, e);
1010
+ }
1011
+ }
1012
+ throw e;
837
1013
  }
1014
+ for (let callback of this.afterDeleteEntityCallbacks) {
1015
+ if (callback) {
1016
+ await callback(this, result);
1017
+ }
1018
+ }
1019
+ return await result;
1020
+ } catch (e: any) {
1021
+ this.config.debugError('nymph', `Failed to delete entity: ${e}`);
1022
+ throw e;
838
1023
  }
839
- return await result;
840
1024
  }
841
1025
 
842
1026
  /**
@@ -848,30 +1032,35 @@ export default class Nymph {
848
1032
  */
849
1033
  public async deleteEntityByID(
850
1034
  guid: string,
851
- className?: string
1035
+ className?: string,
852
1036
  ): Promise<boolean> {
853
- for (let callback of this.beforeDeleteEntityByIDCallbacks) {
854
- if (callback) {
855
- await callback(this, guid, className);
856
- }
857
- }
858
- let result: Promise<boolean>;
859
1037
  try {
860
- result = this.driver.deleteEntityByID(guid, className);
861
- } catch (e: any) {
862
- for (let callback of this.failedDeleteEntityByIDCallbacks) {
1038
+ for (let callback of this.beforeDeleteEntityByIDCallbacks) {
863
1039
  if (callback) {
864
- await callback(this, e);
1040
+ await callback(this, guid, className);
865
1041
  }
866
1042
  }
867
- throw e;
868
- }
869
- for (let callback of this.afterDeleteEntityByIDCallbacks) {
870
- if (callback) {
871
- await callback(this, result);
1043
+ let result: Promise<boolean>;
1044
+ try {
1045
+ result = this.driver.deleteEntityByID(guid, className);
1046
+ } catch (e: any) {
1047
+ for (let callback of this.failedDeleteEntityByIDCallbacks) {
1048
+ if (callback) {
1049
+ await callback(this, e);
1050
+ }
1051
+ }
1052
+ throw e;
872
1053
  }
1054
+ for (let callback of this.afterDeleteEntityByIDCallbacks) {
1055
+ if (callback) {
1056
+ await callback(this, result);
1057
+ }
1058
+ }
1059
+ return await result;
1060
+ } catch (e: any) {
1061
+ this.config.debugError('nymph', `Failed to delete entity by ID: ${e}`);
1062
+ throw e;
873
1063
  }
874
- return await result;
875
1064
  }
876
1065
 
877
1066
  /**
@@ -896,7 +1085,7 @@ export default class Nymph {
896
1085
  * # brackets ([]).
897
1086
  * # Properties are stored like this:
898
1087
  * # propname=JSON.stringify(value)
899
- * abilities=["system/all"]
1088
+ * abilities=["system/admin"]
900
1089
  * groups=[]
901
1090
  * inheritAbilities=false
902
1091
  * name="admin"
@@ -911,7 +1100,12 @@ export default class Nymph {
911
1100
  * @returns True on success, false on failure.
912
1101
  */
913
1102
  public async export(filename: string): Promise<boolean> {
914
- return await this.driver.export(filename);
1103
+ try {
1104
+ return await this.driver.export(filename);
1105
+ } catch (e: any) {
1106
+ this.config.debugError('nymph', `Failed to export: ${e}`);
1107
+ throw e;
1108
+ }
915
1109
  }
916
1110
 
917
1111
  /**
@@ -920,17 +1114,236 @@ export default class Nymph {
920
1114
  * @returns True on success, false on failure.
921
1115
  */
922
1116
  public async exportPrint(): Promise<boolean> {
923
- return await this.driver.exportPrint();
1117
+ try {
1118
+ return await this.driver.exportPrint();
1119
+ } catch (e: any) {
1120
+ this.config.debugError('nymph', `Failed to export: ${e}`);
1121
+ throw e;
1122
+ }
1123
+ }
1124
+
1125
+ public async exportEntity(etype: string, guid: string): Promise<string> {
1126
+ try {
1127
+ return await this.driver.exportEntity(etype, guid);
1128
+ } catch (e: any) {
1129
+ this.config.debugError('nymph', `Failed to export: ${e}`);
1130
+ throw e;
1131
+ }
924
1132
  }
925
1133
 
926
1134
  /**
927
1135
  * Import entities from a file.
928
1136
  *
929
1137
  * @param filename The file to import from.
1138
+ * @param options The options for the import.
930
1139
  * @returns True on success, false on failure.
931
1140
  */
932
- public async import(filename: string): Promise<boolean> {
933
- return await this.driver.import(filename);
1141
+ public async import(
1142
+ filename: string,
1143
+ options?: { ignoreUnknownETypes?: boolean },
1144
+ ): Promise<boolean> {
1145
+ try {
1146
+ return await this.driver.import(filename, options);
1147
+ } catch (e: any) {
1148
+ this.config.debugError('nymph', `Failed to import: ${e}`);
1149
+ throw e;
1150
+ }
1151
+ }
1152
+
1153
+ /**
1154
+ * Import a single entity.
1155
+ *
1156
+ * @param entity The entity data to import.
1157
+ */
1158
+ public async importEntity(entity: {
1159
+ guid: string;
1160
+ cdate: number;
1161
+ mdate: number;
1162
+ tags: string[];
1163
+ sdata: SerializedEntityData;
1164
+ etype: string;
1165
+ }) {
1166
+ try {
1167
+ return await this.driver.importEntity(entity);
1168
+ } catch (e: any) {
1169
+ this.config.debugError('nymph', `Failed to import: ${e}`);
1170
+ throw e;
1171
+ }
1172
+ }
1173
+
1174
+ /**
1175
+ * Import a single entity's tokens.
1176
+ *
1177
+ * This does not update any of the actual data, only the tokens used for full
1178
+ * text search.
1179
+ *
1180
+ * Be careful with this function, since you can overwrite existing tokens with
1181
+ * data that is out of sync. The DB _should_ prevent you from inserting tokens
1182
+ * for an entity that doesn't exist, but it _won't_ prevent you from inserting
1183
+ * tokens for properties that don't exist on an entity.
1184
+ *
1185
+ * @param entity The entity data to import.
1186
+ */
1187
+ public async importEntityTokens(entity: {
1188
+ guid: string;
1189
+ cdate: number;
1190
+ mdate: number;
1191
+ tags: string[];
1192
+ sdata: SerializedEntityData;
1193
+ etype: string;
1194
+ }) {
1195
+ try {
1196
+ return await this.driver.importEntityTokens(entity);
1197
+ } catch (e: any) {
1198
+ this.config.debugError('nymph', `Failed to import: ${e}`);
1199
+ throw e;
1200
+ }
1201
+ }
1202
+
1203
+ /**
1204
+ * Import a single entity's Tilmeld access control properties.
1205
+ *
1206
+ * This does not update any of the other data, only the access control
1207
+ * columns.
1208
+ *
1209
+ * @param entity The entity data to import.
1210
+ */
1211
+ public async importEntityTilmeldAC(entity: {
1212
+ guid: string;
1213
+ cdate: number;
1214
+ mdate: number;
1215
+ tags: string[];
1216
+ sdata: SerializedEntityData;
1217
+ etype: string;
1218
+ }) {
1219
+ try {
1220
+ return await this.driver.importEntityTilmeldAC(entity);
1221
+ } catch (e: any) {
1222
+ this.config.debugError('nymph', `Failed to import: ${e}`);
1223
+ throw e;
1224
+ }
1225
+ }
1226
+
1227
+ /**
1228
+ * Detect whether the database needs to be migrated.
1229
+ *
1230
+ * If not false (so, one of the string values), the database should be
1231
+ * exported with an old version of Nymph, then imported into a fresh database
1232
+ * with this version. Sometimes, a live migration can be done instead, which
1233
+ * will require no downtime. You should still export the database beforehand,
1234
+ * in case anything goes wrong.
1235
+ *
1236
+ * 'json' means the data tables are missing the JSON field, and the DB
1237
+ * **must** be exported and imported to fix it.
1238
+ *
1239
+ * 'tokens' means the FTS token tables are missing, and you can get away with
1240
+ * a live migration with `liveMigration('tokenTables')` and doing
1241
+ * `importEntityTokens(entity)` for each entity.
1242
+ *
1243
+ * 'tilmeldColumns' means the entity columns for "user", "group", and access
1244
+ * controls are missing, and you can get away with a live migration with
1245
+ * `liveMigration('tilmeldColumns')` and doing
1246
+ * `importEntityTilmeldAC(entity)` for each entity. DO NOT update to any
1247
+ * version later than 1.0.0-beta.109 before this is done, or access controls
1248
+ * WILL NOT work, and everyone will have access to every entity!
1249
+ */
1250
+ public async needsMigration() {
1251
+ return await this.driver.needsMigration();
1252
+ }
1253
+
1254
+ /**
1255
+ * Perform a live migration on the DB.
1256
+ *
1257
+ * A 'tokenTables' migration will simply add the missing token tables. It will
1258
+ * **not** fill them. You must use `importEntityTokens` on each entity after
1259
+ * running this to fill the token tables and enable full text search matching
1260
+ * on existing entities.
1261
+ *
1262
+ * A 'tilmeldColumns' migration will simply add the missing Tilmeld columns
1263
+ * and indexes to each entity table. It will **not** fill them, and you must
1264
+ * fill them before updating to the latest version of Nymph, or everyone will
1265
+ * be able to access every entity! You must use `importEntityTilmeldAC` on
1266
+ * each entity after running this.
1267
+ *
1268
+ * A 'tilmeldRemoveOldRows' migration will remove all of the old access
1269
+ * control rows in the data tables that are no longer used as of
1270
+ * 1.0.0-beta.110. MAKE SURE YOU HAVE RUN `importEntityTilmeldAC` ON ALL
1271
+ * ENTITIES BEFORE RUNNING THIS, OR THE DATA WILL BE IRRETRIEVABLY LOST!
1272
+ */
1273
+ public async liveMigration(
1274
+ migrationType: 'tokenTables' | 'tilmeldColumns' | 'tilmeldRemoveOldRows',
1275
+ ) {
1276
+ return await this.driver.liveMigration(migrationType);
1277
+ }
1278
+
1279
+ /**
1280
+ * Returns a list of the etypes stored in the DB.
1281
+ */
1282
+ public async getEtypes() {
1283
+ return await this.driver.getEtypes();
1284
+ }
1285
+
1286
+ /**
1287
+ * Get all the indexes defined for a specific etype.
1288
+ *
1289
+ * @param etype The etype to get indexes for.
1290
+ */
1291
+ public async getIndexes(etype: string) {
1292
+ return await this.driver.getIndexes(etype);
1293
+ }
1294
+
1295
+ /**
1296
+ * Add an index on a specific property to an etype.
1297
+ *
1298
+ * Nymph adds general indexes on etypes, but they span across all properties,
1299
+ * so they can only speed up a query so much. You can add indexes that are
1300
+ * specific to a property with this function, which will speed up queries for
1301
+ * that property. If an etype only has one or two properties, you may not need
1302
+ * a specific index, but if your etypes include many properties or properties
1303
+ * that generally contain large amounts of data, adding a specific index can
1304
+ * drastically improve the performance of your queries.
1305
+ *
1306
+ * The scope of the index will affect which queries it will speed up:
1307
+ *
1308
+ * - data: This will speed up comparisons and equality checks in queries.
1309
+ * - references: This will speed up ref and qref clauses in queries.
1310
+ * - tokens: This will speed up search clauses in queries.
1311
+ *
1312
+ * The name must be unique within the etype and scope or the existing index
1313
+ * will be overwritten.
1314
+ *
1315
+ * You do not need to add reference indexes for the "user" and "group"
1316
+ * properties, because these are already specifically indexed by Nymph.
1317
+ *
1318
+ * @param etype The etype to add the index on.
1319
+ * @param definition The definition of the index.
1320
+ */
1321
+ public async addIndex(
1322
+ etype: string,
1323
+ definition: {
1324
+ scope: 'data' | 'references' | 'tokens';
1325
+ name: string;
1326
+ property: string;
1327
+ },
1328
+ ) {
1329
+ this.driver.checkIndexName(definition.name);
1330
+ return await this.driver.addIndex(etype, definition);
1331
+ }
1332
+
1333
+ /**
1334
+ * Delete an index from an etype.
1335
+ *
1336
+ * @param etype The etype to delete the index on.
1337
+ * @param scope The scope of the index.
1338
+ * @param name The name of the index to delete.
1339
+ */
1340
+ public async deleteIndex(
1341
+ etype: string,
1342
+ scope: 'data' | 'references' | 'tokens',
1343
+ name: string,
1344
+ ) {
1345
+ this.driver.checkIndexName(name);
1346
+ return await this.driver.deleteIndex(etype, scope, name);
934
1347
  }
935
1348
 
936
1349
  public on<T extends NymphEventType>(
@@ -938,134 +1351,134 @@ export default class Nymph {
938
1351
  callback: T extends 'connect'
939
1352
  ? NymphConnectCallback
940
1353
  : T extends 'disconnect'
941
- ? NymphDisconnectCallback
942
- : T extends 'query'
943
- ? NymphQueryCallback
944
- : T extends 'beforeGetEntity'
945
- ? NymphBeforeGetEntityCallback
946
- : T extends 'beforeGetEntities'
947
- ? NymphBeforeGetEntitiesCallback
948
- : T extends 'beforeSaveEntity'
949
- ? NymphBeforeSaveEntityCallback
950
- : T extends 'afterSaveEntity'
951
- ? NymphAfterSaveEntityCallback
952
- : T extends 'failedSaveEntity'
953
- ? NymphFailedSaveEntityCallback
954
- : T extends 'beforeDeleteEntity'
955
- ? NymphBeforeDeleteEntityCallback
956
- : T extends 'afterDeleteEntity'
957
- ? NymphAfterDeleteEntityCallback
958
- : T extends 'failedDeleteEntity'
959
- ? NymphFailedDeleteEntityCallback
960
- : T extends 'beforeDeleteEntityByID'
961
- ? NymphBeforeDeleteEntityByIDCallback
962
- : T extends 'afterDeleteEntityByID'
963
- ? NymphAfterDeleteEntityByIDCallback
964
- : T extends 'failedDeleteEntityByID'
965
- ? NymphFailedDeleteEntityByIDCallback
966
- : T extends 'beforeNewUID'
967
- ? NymphBeforeNewUIDCallback
968
- : T extends 'afterNewUID'
969
- ? NymphAfterNewUIDCallback
970
- : T extends 'failedNewUID'
971
- ? NymphFailedNewUIDCallback
972
- : T extends 'beforeSetUID'
973
- ? NymphBeforeSetUIDCallback
974
- : T extends 'afterSetUID'
975
- ? NymphAfterSetUIDCallback
976
- : T extends 'failedSetUID'
977
- ? NymphFailedSetUIDCallback
978
- : T extends 'beforeRenameUID'
979
- ? NymphBeforeRenameUIDCallback
980
- : T extends 'afterRenameUID'
981
- ? NymphAfterRenameUIDCallback
982
- : T extends 'failedRenameUID'
983
- ? NymphFailedRenameUIDCallback
984
- : T extends 'beforeDeleteUID'
985
- ? NymphBeforeDeleteUIDCallback
986
- : T extends 'afterDeleteUID'
987
- ? NymphAfterDeleteUIDCallback
988
- : T extends 'failedDeleteUID'
989
- ? NymphFailedDeleteUIDCallback
990
- : T extends 'beforeStartTransaction'
991
- ? NymphBeforeStartTransactionCallback
992
- : T extends 'afterStartTransaction'
993
- ? NymphAfterStartTransactionCallback
994
- : T extends 'beforeCommitTransaction'
995
- ? NymphBeforeCommitTransactionCallback
996
- : T extends 'afterCommitTransaction'
997
- ? NymphAfterCommitTransactionCallback
998
- : T extends 'beforeRollbackTransaction'
999
- ? NymphBeforeRollbackTransactionCallback
1000
- : T extends 'afterRollbackTransaction'
1001
- ? NymphAfterRollbackTransactionCallback
1002
- : never
1354
+ ? NymphDisconnectCallback
1355
+ : T extends 'query'
1356
+ ? NymphQueryCallback
1357
+ : T extends 'beforeGetEntity'
1358
+ ? NymphBeforeGetEntityCallback
1359
+ : T extends 'beforeGetEntities'
1360
+ ? NymphBeforeGetEntitiesCallback
1361
+ : T extends 'beforeSaveEntity'
1362
+ ? NymphBeforeSaveEntityCallback
1363
+ : T extends 'afterSaveEntity'
1364
+ ? NymphAfterSaveEntityCallback
1365
+ : T extends 'failedSaveEntity'
1366
+ ? NymphFailedSaveEntityCallback
1367
+ : T extends 'beforeDeleteEntity'
1368
+ ? NymphBeforeDeleteEntityCallback
1369
+ : T extends 'afterDeleteEntity'
1370
+ ? NymphAfterDeleteEntityCallback
1371
+ : T extends 'failedDeleteEntity'
1372
+ ? NymphFailedDeleteEntityCallback
1373
+ : T extends 'beforeDeleteEntityByID'
1374
+ ? NymphBeforeDeleteEntityByIDCallback
1375
+ : T extends 'afterDeleteEntityByID'
1376
+ ? NymphAfterDeleteEntityByIDCallback
1377
+ : T extends 'failedDeleteEntityByID'
1378
+ ? NymphFailedDeleteEntityByIDCallback
1379
+ : T extends 'beforeNewUID'
1380
+ ? NymphBeforeNewUIDCallback
1381
+ : T extends 'afterNewUID'
1382
+ ? NymphAfterNewUIDCallback
1383
+ : T extends 'failedNewUID'
1384
+ ? NymphFailedNewUIDCallback
1385
+ : T extends 'beforeSetUID'
1386
+ ? NymphBeforeSetUIDCallback
1387
+ : T extends 'afterSetUID'
1388
+ ? NymphAfterSetUIDCallback
1389
+ : T extends 'failedSetUID'
1390
+ ? NymphFailedSetUIDCallback
1391
+ : T extends 'beforeRenameUID'
1392
+ ? NymphBeforeRenameUIDCallback
1393
+ : T extends 'afterRenameUID'
1394
+ ? NymphAfterRenameUIDCallback
1395
+ : T extends 'failedRenameUID'
1396
+ ? NymphFailedRenameUIDCallback
1397
+ : T extends 'beforeDeleteUID'
1398
+ ? NymphBeforeDeleteUIDCallback
1399
+ : T extends 'afterDeleteUID'
1400
+ ? NymphAfterDeleteUIDCallback
1401
+ : T extends 'failedDeleteUID'
1402
+ ? NymphFailedDeleteUIDCallback
1403
+ : T extends 'beforeStartTransaction'
1404
+ ? NymphBeforeStartTransactionCallback
1405
+ : T extends 'afterStartTransaction'
1406
+ ? NymphAfterStartTransactionCallback
1407
+ : T extends 'beforeCommitTransaction'
1408
+ ? NymphBeforeCommitTransactionCallback
1409
+ : T extends 'afterCommitTransaction'
1410
+ ? NymphAfterCommitTransactionCallback
1411
+ : T extends 'beforeRollbackTransaction'
1412
+ ? NymphBeforeRollbackTransactionCallback
1413
+ : T extends 'afterRollbackTransaction'
1414
+ ? NymphAfterRollbackTransactionCallback
1415
+ : never,
1003
1416
  ) {
1004
1417
  const prop = (event + 'Callbacks') as T extends 'connect'
1005
1418
  ? 'connectCallbacks'
1006
1419
  : T extends 'disconnect'
1007
- ? 'disconnectCallbacks'
1008
- : T extends 'query'
1009
- ? 'queryCallbacks'
1010
- : T extends 'beforeGetEntity'
1011
- ? 'beforeGetEntityCallbacks'
1012
- : T extends 'beforeGetEntities'
1013
- ? 'beforeGetEntitiesCallbacks'
1014
- : T extends 'beforeSaveEntity'
1015
- ? 'beforeSaveEntityCallbacks'
1016
- : T extends 'afterSaveEntity'
1017
- ? 'afterSaveEntityCallbacks'
1018
- : T extends 'failedSaveEntity'
1019
- ? 'failedSaveEntityCallbacks'
1020
- : T extends 'beforeDeleteEntity'
1021
- ? 'beforeDeleteEntityCallbacks'
1022
- : T extends 'afterDeleteEntity'
1023
- ? 'afterDeleteEntityCallbacks'
1024
- : T extends 'failedDeleteEntity'
1025
- ? 'failedDeleteEntityCallbacks'
1026
- : T extends 'beforeDeleteEntityByID'
1027
- ? 'beforeDeleteEntityByIDCallbacks'
1028
- : T extends 'afterDeleteEntityByID'
1029
- ? 'afterDeleteEntityByIDCallbacks'
1030
- : T extends 'failedDeleteEntityByID'
1031
- ? 'failedDeleteEntityByIDCallbacks'
1032
- : T extends 'beforeNewUID'
1033
- ? 'beforeNewUIDCallbacks'
1034
- : T extends 'afterNewUID'
1035
- ? 'afterNewUIDCallbacks'
1036
- : T extends 'failedNewUID'
1037
- ? 'failedNewUIDCallbacks'
1038
- : T extends 'beforeSetUID'
1039
- ? 'beforeSetUIDCallbacks'
1040
- : T extends 'afterSetUID'
1041
- ? 'afterSetUIDCallbacks'
1042
- : T extends 'failedSetUID'
1043
- ? 'failedSetUIDCallbacks'
1044
- : T extends 'beforeRenameUID'
1045
- ? 'beforeRenameUIDCallbacks'
1046
- : T extends 'afterRenameUID'
1047
- ? 'afterRenameUIDCallbacks'
1048
- : T extends 'failedRenameUID'
1049
- ? 'failedRenameUIDCallbacks'
1050
- : T extends 'beforeDeleteUID'
1051
- ? 'beforeDeleteUIDCallbacks'
1052
- : T extends 'afterDeleteUID'
1053
- ? 'afterDeleteUIDCallbacks'
1054
- : T extends 'failedDeleteUID'
1055
- ? 'failedDeleteUIDCallbacks'
1056
- : T extends 'beforeStartTransaction'
1057
- ? 'beforeStartTransactionCallbacks'
1058
- : T extends 'afterStartTransaction'
1059
- ? 'afterStartTransactionCallbacks'
1060
- : T extends 'beforeCommitTransaction'
1061
- ? 'beforeCommitTransactionCallbacks'
1062
- : T extends 'afterCommitTransaction'
1063
- ? 'afterCommitTransactionCallbacks'
1064
- : T extends 'beforeRollbackTransaction'
1065
- ? 'beforeRollbackTransactionCallbacks'
1066
- : T extends 'afterRollbackTransaction'
1067
- ? 'afterRollbackTransactionCallbacks'
1068
- : never;
1420
+ ? 'disconnectCallbacks'
1421
+ : T extends 'query'
1422
+ ? 'queryCallbacks'
1423
+ : T extends 'beforeGetEntity'
1424
+ ? 'beforeGetEntityCallbacks'
1425
+ : T extends 'beforeGetEntities'
1426
+ ? 'beforeGetEntitiesCallbacks'
1427
+ : T extends 'beforeSaveEntity'
1428
+ ? 'beforeSaveEntityCallbacks'
1429
+ : T extends 'afterSaveEntity'
1430
+ ? 'afterSaveEntityCallbacks'
1431
+ : T extends 'failedSaveEntity'
1432
+ ? 'failedSaveEntityCallbacks'
1433
+ : T extends 'beforeDeleteEntity'
1434
+ ? 'beforeDeleteEntityCallbacks'
1435
+ : T extends 'afterDeleteEntity'
1436
+ ? 'afterDeleteEntityCallbacks'
1437
+ : T extends 'failedDeleteEntity'
1438
+ ? 'failedDeleteEntityCallbacks'
1439
+ : T extends 'beforeDeleteEntityByID'
1440
+ ? 'beforeDeleteEntityByIDCallbacks'
1441
+ : T extends 'afterDeleteEntityByID'
1442
+ ? 'afterDeleteEntityByIDCallbacks'
1443
+ : T extends 'failedDeleteEntityByID'
1444
+ ? 'failedDeleteEntityByIDCallbacks'
1445
+ : T extends 'beforeNewUID'
1446
+ ? 'beforeNewUIDCallbacks'
1447
+ : T extends 'afterNewUID'
1448
+ ? 'afterNewUIDCallbacks'
1449
+ : T extends 'failedNewUID'
1450
+ ? 'failedNewUIDCallbacks'
1451
+ : T extends 'beforeSetUID'
1452
+ ? 'beforeSetUIDCallbacks'
1453
+ : T extends 'afterSetUID'
1454
+ ? 'afterSetUIDCallbacks'
1455
+ : T extends 'failedSetUID'
1456
+ ? 'failedSetUIDCallbacks'
1457
+ : T extends 'beforeRenameUID'
1458
+ ? 'beforeRenameUIDCallbacks'
1459
+ : T extends 'afterRenameUID'
1460
+ ? 'afterRenameUIDCallbacks'
1461
+ : T extends 'failedRenameUID'
1462
+ ? 'failedRenameUIDCallbacks'
1463
+ : T extends 'beforeDeleteUID'
1464
+ ? 'beforeDeleteUIDCallbacks'
1465
+ : T extends 'afterDeleteUID'
1466
+ ? 'afterDeleteUIDCallbacks'
1467
+ : T extends 'failedDeleteUID'
1468
+ ? 'failedDeleteUIDCallbacks'
1469
+ : T extends 'beforeStartTransaction'
1470
+ ? 'beforeStartTransactionCallbacks'
1471
+ : T extends 'afterStartTransaction'
1472
+ ? 'afterStartTransactionCallbacks'
1473
+ : T extends 'beforeCommitTransaction'
1474
+ ? 'beforeCommitTransactionCallbacks'
1475
+ : T extends 'afterCommitTransaction'
1476
+ ? 'afterCommitTransactionCallbacks'
1477
+ : T extends 'beforeRollbackTransaction'
1478
+ ? 'beforeRollbackTransactionCallbacks'
1479
+ : T extends 'afterRollbackTransaction'
1480
+ ? 'afterRollbackTransactionCallbacks'
1481
+ : never;
1069
1482
  if (!(prop in this)) {
1070
1483
  throw new Error('Invalid event type.');
1071
1484
  }
@@ -1079,134 +1492,134 @@ export default class Nymph {
1079
1492
  callback: T extends 'connect'
1080
1493
  ? NymphConnectCallback
1081
1494
  : T extends 'disconnect'
1082
- ? NymphDisconnectCallback
1083
- : T extends 'query'
1084
- ? NymphQueryCallback
1085
- : T extends 'beforeGetEntity'
1086
- ? NymphBeforeGetEntityCallback
1087
- : T extends 'beforeGetEntities'
1088
- ? NymphBeforeGetEntitiesCallback
1089
- : T extends 'beforeSaveEntity'
1090
- ? NymphBeforeSaveEntityCallback
1091
- : T extends 'afterSaveEntity'
1092
- ? NymphAfterSaveEntityCallback
1093
- : T extends 'failedSaveEntity'
1094
- ? NymphFailedSaveEntityCallback
1095
- : T extends 'beforeDeleteEntity'
1096
- ? NymphBeforeDeleteEntityCallback
1097
- : T extends 'afterDeleteEntity'
1098
- ? NymphAfterDeleteEntityCallback
1099
- : T extends 'failedDeleteEntity'
1100
- ? NymphFailedDeleteEntityCallback
1101
- : T extends 'beforeDeleteEntityByID'
1102
- ? NymphBeforeDeleteEntityByIDCallback
1103
- : T extends 'afterDeleteEntityByID'
1104
- ? NymphAfterDeleteEntityByIDCallback
1105
- : T extends 'failedDeleteEntityByID'
1106
- ? NymphFailedDeleteEntityByIDCallback
1107
- : T extends 'beforeNewUID'
1108
- ? NymphBeforeNewUIDCallback
1109
- : T extends 'afterNewUID'
1110
- ? NymphAfterNewUIDCallback
1111
- : T extends 'failedNewUID'
1112
- ? NymphFailedNewUIDCallback
1113
- : T extends 'beforeSetUID'
1114
- ? NymphBeforeSetUIDCallback
1115
- : T extends 'afterSetUID'
1116
- ? NymphAfterSetUIDCallback
1117
- : T extends 'failedSetUID'
1118
- ? NymphFailedSetUIDCallback
1119
- : T extends 'beforeRenameUID'
1120
- ? NymphBeforeRenameUIDCallback
1121
- : T extends 'afterRenameUID'
1122
- ? NymphAfterRenameUIDCallback
1123
- : T extends 'failedRenameUID'
1124
- ? NymphFailedRenameUIDCallback
1125
- : T extends 'beforeDeleteUID'
1126
- ? NymphBeforeDeleteUIDCallback
1127
- : T extends 'afterDeleteUID'
1128
- ? NymphAfterDeleteUIDCallback
1129
- : T extends 'failedDeleteUID'
1130
- ? NymphFailedDeleteUIDCallback
1131
- : T extends 'beforeStartTransaction'
1132
- ? NymphBeforeStartTransactionCallback
1133
- : T extends 'afterStartTransaction'
1134
- ? NymphAfterStartTransactionCallback
1135
- : T extends 'beforeCommitTransaction'
1136
- ? NymphBeforeCommitTransactionCallback
1137
- : T extends 'afterCommitTransaction'
1138
- ? NymphAfterCommitTransactionCallback
1139
- : T extends 'beforeRollbackTransaction'
1140
- ? NymphBeforeRollbackTransactionCallback
1141
- : T extends 'afterRollbackTransaction'
1142
- ? NymphAfterRollbackTransactionCallback
1143
- : never
1495
+ ? NymphDisconnectCallback
1496
+ : T extends 'query'
1497
+ ? NymphQueryCallback
1498
+ : T extends 'beforeGetEntity'
1499
+ ? NymphBeforeGetEntityCallback
1500
+ : T extends 'beforeGetEntities'
1501
+ ? NymphBeforeGetEntitiesCallback
1502
+ : T extends 'beforeSaveEntity'
1503
+ ? NymphBeforeSaveEntityCallback
1504
+ : T extends 'afterSaveEntity'
1505
+ ? NymphAfterSaveEntityCallback
1506
+ : T extends 'failedSaveEntity'
1507
+ ? NymphFailedSaveEntityCallback
1508
+ : T extends 'beforeDeleteEntity'
1509
+ ? NymphBeforeDeleteEntityCallback
1510
+ : T extends 'afterDeleteEntity'
1511
+ ? NymphAfterDeleteEntityCallback
1512
+ : T extends 'failedDeleteEntity'
1513
+ ? NymphFailedDeleteEntityCallback
1514
+ : T extends 'beforeDeleteEntityByID'
1515
+ ? NymphBeforeDeleteEntityByIDCallback
1516
+ : T extends 'afterDeleteEntityByID'
1517
+ ? NymphAfterDeleteEntityByIDCallback
1518
+ : T extends 'failedDeleteEntityByID'
1519
+ ? NymphFailedDeleteEntityByIDCallback
1520
+ : T extends 'beforeNewUID'
1521
+ ? NymphBeforeNewUIDCallback
1522
+ : T extends 'afterNewUID'
1523
+ ? NymphAfterNewUIDCallback
1524
+ : T extends 'failedNewUID'
1525
+ ? NymphFailedNewUIDCallback
1526
+ : T extends 'beforeSetUID'
1527
+ ? NymphBeforeSetUIDCallback
1528
+ : T extends 'afterSetUID'
1529
+ ? NymphAfterSetUIDCallback
1530
+ : T extends 'failedSetUID'
1531
+ ? NymphFailedSetUIDCallback
1532
+ : T extends 'beforeRenameUID'
1533
+ ? NymphBeforeRenameUIDCallback
1534
+ : T extends 'afterRenameUID'
1535
+ ? NymphAfterRenameUIDCallback
1536
+ : T extends 'failedRenameUID'
1537
+ ? NymphFailedRenameUIDCallback
1538
+ : T extends 'beforeDeleteUID'
1539
+ ? NymphBeforeDeleteUIDCallback
1540
+ : T extends 'afterDeleteUID'
1541
+ ? NymphAfterDeleteUIDCallback
1542
+ : T extends 'failedDeleteUID'
1543
+ ? NymphFailedDeleteUIDCallback
1544
+ : T extends 'beforeStartTransaction'
1545
+ ? NymphBeforeStartTransactionCallback
1546
+ : T extends 'afterStartTransaction'
1547
+ ? NymphAfterStartTransactionCallback
1548
+ : T extends 'beforeCommitTransaction'
1549
+ ? NymphBeforeCommitTransactionCallback
1550
+ : T extends 'afterCommitTransaction'
1551
+ ? NymphAfterCommitTransactionCallback
1552
+ : T extends 'beforeRollbackTransaction'
1553
+ ? NymphBeforeRollbackTransactionCallback
1554
+ : T extends 'afterRollbackTransaction'
1555
+ ? NymphAfterRollbackTransactionCallback
1556
+ : never,
1144
1557
  ) {
1145
1558
  const prop = (event + 'Callbacks') as T extends 'connect'
1146
1559
  ? 'connectCallbacks'
1147
1560
  : T extends 'disconnect'
1148
- ? 'disconnectCallbacks'
1149
- : T extends 'query'
1150
- ? 'queryCallbacks'
1151
- : T extends 'beforeSaveEntity'
1152
- ? 'beforeSaveEntityCallbacks'
1153
- : T extends 'beforeGetEntity'
1154
- ? 'beforeGetEntityCallbacks'
1155
- : T extends 'beforeGetEntities'
1156
- ? 'beforeGetEntitiesCallbacks'
1157
- : T extends 'afterSaveEntity'
1158
- ? 'afterSaveEntityCallbacks'
1159
- : T extends 'failedSaveEntity'
1160
- ? 'failedSaveEntityCallbacks'
1161
- : T extends 'beforeDeleteEntity'
1162
- ? 'beforeDeleteEntityCallbacks'
1163
- : T extends 'afterDeleteEntity'
1164
- ? 'afterDeleteEntityCallbacks'
1165
- : T extends 'failedDeleteEntity'
1166
- ? 'failedDeleteEntityCallbacks'
1167
- : T extends 'beforeDeleteEntityByID'
1168
- ? 'beforeDeleteEntityByIDCallbacks'
1169
- : T extends 'afterDeleteEntityByID'
1170
- ? 'afterDeleteEntityByIDCallbacks'
1171
- : T extends 'failedDeleteEntityByID'
1172
- ? 'failedDeleteEntityByIDCallbacks'
1173
- : T extends 'beforeNewUID'
1174
- ? 'beforeNewUIDCallbacks'
1175
- : T extends 'afterNewUID'
1176
- ? 'afterNewUIDCallbacks'
1177
- : T extends 'failedNewUID'
1178
- ? 'failedNewUIDCallbacks'
1179
- : T extends 'beforeSetUID'
1180
- ? 'beforeSetUIDCallbacks'
1181
- : T extends 'afterSetUID'
1182
- ? 'afterSetUIDCallbacks'
1183
- : T extends 'failedSetUID'
1184
- ? 'failedSetUIDCallbacks'
1185
- : T extends 'beforeRenameUID'
1186
- ? 'beforeRenameUIDCallbacks'
1187
- : T extends 'afterRenameUID'
1188
- ? 'afterRenameUIDCallbacks'
1189
- : T extends 'failedRenameUID'
1190
- ? 'failedRenameUIDCallbacks'
1191
- : T extends 'beforeDeleteUID'
1192
- ? 'beforeDeleteUIDCallbacks'
1193
- : T extends 'afterDeleteUID'
1194
- ? 'afterDeleteUIDCallbacks'
1195
- : T extends 'failedDeleteUID'
1196
- ? 'failedDeleteUIDCallbacks'
1197
- : T extends 'beforeStartTransaction'
1198
- ? 'beforeStartTransactionCallbacks'
1199
- : T extends 'afterStartTransaction'
1200
- ? 'afterStartTransactionCallbacks'
1201
- : T extends 'beforeCommitTransaction'
1202
- ? 'beforeCommitTransactionCallbacks'
1203
- : T extends 'afterCommitTransaction'
1204
- ? 'afterCommitTransactionCallbacks'
1205
- : T extends 'beforeRollbackTransaction'
1206
- ? 'beforeRollbackTransactionCallbacks'
1207
- : T extends 'afterRollbackTransaction'
1208
- ? 'afterRollbackTransactionCallbacks'
1209
- : never;
1561
+ ? 'disconnectCallbacks'
1562
+ : T extends 'query'
1563
+ ? 'queryCallbacks'
1564
+ : T extends 'beforeSaveEntity'
1565
+ ? 'beforeSaveEntityCallbacks'
1566
+ : T extends 'beforeGetEntity'
1567
+ ? 'beforeGetEntityCallbacks'
1568
+ : T extends 'beforeGetEntities'
1569
+ ? 'beforeGetEntitiesCallbacks'
1570
+ : T extends 'afterSaveEntity'
1571
+ ? 'afterSaveEntityCallbacks'
1572
+ : T extends 'failedSaveEntity'
1573
+ ? 'failedSaveEntityCallbacks'
1574
+ : T extends 'beforeDeleteEntity'
1575
+ ? 'beforeDeleteEntityCallbacks'
1576
+ : T extends 'afterDeleteEntity'
1577
+ ? 'afterDeleteEntityCallbacks'
1578
+ : T extends 'failedDeleteEntity'
1579
+ ? 'failedDeleteEntityCallbacks'
1580
+ : T extends 'beforeDeleteEntityByID'
1581
+ ? 'beforeDeleteEntityByIDCallbacks'
1582
+ : T extends 'afterDeleteEntityByID'
1583
+ ? 'afterDeleteEntityByIDCallbacks'
1584
+ : T extends 'failedDeleteEntityByID'
1585
+ ? 'failedDeleteEntityByIDCallbacks'
1586
+ : T extends 'beforeNewUID'
1587
+ ? 'beforeNewUIDCallbacks'
1588
+ : T extends 'afterNewUID'
1589
+ ? 'afterNewUIDCallbacks'
1590
+ : T extends 'failedNewUID'
1591
+ ? 'failedNewUIDCallbacks'
1592
+ : T extends 'beforeSetUID'
1593
+ ? 'beforeSetUIDCallbacks'
1594
+ : T extends 'afterSetUID'
1595
+ ? 'afterSetUIDCallbacks'
1596
+ : T extends 'failedSetUID'
1597
+ ? 'failedSetUIDCallbacks'
1598
+ : T extends 'beforeRenameUID'
1599
+ ? 'beforeRenameUIDCallbacks'
1600
+ : T extends 'afterRenameUID'
1601
+ ? 'afterRenameUIDCallbacks'
1602
+ : T extends 'failedRenameUID'
1603
+ ? 'failedRenameUIDCallbacks'
1604
+ : T extends 'beforeDeleteUID'
1605
+ ? 'beforeDeleteUIDCallbacks'
1606
+ : T extends 'afterDeleteUID'
1607
+ ? 'afterDeleteUIDCallbacks'
1608
+ : T extends 'failedDeleteUID'
1609
+ ? 'failedDeleteUIDCallbacks'
1610
+ : T extends 'beforeStartTransaction'
1611
+ ? 'beforeStartTransactionCallbacks'
1612
+ : T extends 'afterStartTransaction'
1613
+ ? 'afterStartTransactionCallbacks'
1614
+ : T extends 'beforeCommitTransaction'
1615
+ ? 'beforeCommitTransactionCallbacks'
1616
+ : T extends 'afterCommitTransaction'
1617
+ ? 'afterCommitTransactionCallbacks'
1618
+ : T extends 'beforeRollbackTransaction'
1619
+ ? 'beforeRollbackTransactionCallbacks'
1620
+ : T extends 'afterRollbackTransaction'
1621
+ ? 'afterRollbackTransactionCallbacks'
1622
+ : never;
1210
1623
  if (!(prop in this)) {
1211
1624
  return false;
1212
1625
  }