@nymphjs/nymph 1.0.0-beta.40 → 1.0.0-beta.41

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/Entity.ts CHANGED
@@ -11,7 +11,12 @@ import {
11
11
  EntityReference,
12
12
  SerializedEntityData,
13
13
  } from './Entity.types';
14
- import { EntityConflictError, InvalidParametersError } from './errors';
14
+ import {
15
+ EntityConflictError,
16
+ EntityIsSleepingReferenceError,
17
+ InvalidParametersError,
18
+ InvalidStateError,
19
+ } from './errors';
15
20
  import {
16
21
  entitiesToReferences,
17
22
  referencesToEntities,
@@ -136,6 +141,10 @@ export default class Entity<T extends EntityData = EntityData>
136
141
  * The reference to use to wake.
137
142
  */
138
143
  protected $sleepingReference: EntityReference | null = null;
144
+ /**
145
+ * A promise that resolved when the entity's data is wake.
146
+ */
147
+ protected $wakePromise: Promise<Entity<T>> | null = null;
139
148
  /**
140
149
  * Properties that will not be serialized into JSON with toJSON(). This
141
150
  * can be considered a denylist, because these properties will not be set
@@ -222,20 +231,19 @@ export default class Entity<T extends EntityData = EntityData>
222
231
  private $originalAcValues: ACProperties | null = null;
223
232
 
224
233
  /**
225
- * Load an entity.
226
- * @param guid The ID of the entity to load, undefined for a new entity.
234
+ * Initialize an entity.
227
235
  */
228
- public constructor(guid?: string) {
236
+ public constructor() {
229
237
  this.$nymph = (this.constructor as EntityConstructor).nymph;
230
238
  this.$dataHandler = {
231
239
  has: (data: EntityData, name: string) => {
232
- this.$referenceWake();
240
+ this.$check();
233
241
 
234
242
  return name in data || name in this.$sdata;
235
243
  },
236
244
 
237
245
  get: (data: EntityData, name: string) => {
238
- this.$referenceWake();
246
+ this.$check();
239
247
 
240
248
  if (this.$sdata.hasOwnProperty(name)) {
241
249
  data[name] = referencesToEntities(
@@ -252,7 +260,7 @@ export default class Entity<T extends EntityData = EntityData>
252
260
  },
253
261
 
254
262
  set: (data: EntityData, name: string, value: any) => {
255
- this.$referenceWake();
263
+ this.$check();
256
264
 
257
265
  if (this.$sdata.hasOwnProperty(name)) {
258
266
  delete this.$sdata[name];
@@ -262,7 +270,7 @@ export default class Entity<T extends EntityData = EntityData>
262
270
  },
263
271
 
264
272
  deleteProperty: (data: EntityData, name: string) => {
265
- this.$referenceWake();
273
+ this.$check();
266
274
 
267
275
  if (this.$sdata.hasOwnProperty(name)) {
268
276
  return delete this.$sdata[name];
@@ -278,7 +286,7 @@ export default class Entity<T extends EntityData = EntityData>
278
286
  name: string,
279
287
  descriptor: PropertyDescriptor
280
288
  ) => {
281
- this.$referenceWake();
289
+ this.$check();
282
290
 
283
291
  if (this.$sdata.hasOwnProperty(name)) {
284
292
  delete this.$sdata[name];
@@ -288,7 +296,7 @@ export default class Entity<T extends EntityData = EntityData>
288
296
  },
289
297
 
290
298
  getOwnPropertyDescriptor: (data: EntityData, name: string) => {
291
- this.$referenceWake();
299
+ this.$check();
292
300
 
293
301
  if (this.$sdata.hasOwnProperty(name)) {
294
302
  data[name] = referencesToEntities(
@@ -302,7 +310,7 @@ export default class Entity<T extends EntityData = EntityData>
302
310
  },
303
311
 
304
312
  ownKeys: (data: EntityData) => {
305
- this.$referenceWake();
313
+ this.$check();
306
314
 
307
315
  return Object.getOwnPropertyNames(data).concat(
308
316
  Object.getOwnPropertyNames(this.$sdata)
@@ -314,24 +322,6 @@ export default class Entity<T extends EntityData = EntityData>
314
322
 
315
323
  this.$data = new Proxy(this.$dataStore, this.$dataHandler);
316
324
 
317
- if (guid != null) {
318
- const entity = this.$nymph.driver.getEntitySync(
319
- {
320
- class: this.$nymph.getEntityClass(
321
- this.constructor as EntityConstructor
322
- ),
323
- },
324
- { type: '&', guid }
325
- );
326
- if (entity) {
327
- this.guid = entity.guid;
328
- this.tags = entity.tags;
329
- this.cdate = entity.cdate;
330
- this.mdate = entity.mdate;
331
- this.$putData(entity.$getData(), entity.$getSData());
332
- }
333
- }
334
-
335
325
  return new Proxy(this, {
336
326
  has: (entity: Entity, name: string) => {
337
327
  if (
@@ -342,7 +332,7 @@ export default class Entity<T extends EntityData = EntityData>
342
332
  return name in entity;
343
333
  }
344
334
 
345
- this.$referenceWake();
335
+ this.$check();
346
336
  return name in entity.$data;
347
337
  },
348
338
 
@@ -353,12 +343,12 @@ export default class Entity<T extends EntityData = EntityData>
353
343
  name.substring(0, 1) === '$'
354
344
  ) {
355
345
  if (name === 'tags' || name === 'cdate' || name === 'mdate') {
356
- this.$referenceWake();
346
+ this.$check();
357
347
  }
358
348
  return (entity as any)[name];
359
349
  }
360
350
 
361
- this.$referenceWake();
351
+ this.$check();
362
352
  if (name in entity.$data) {
363
353
  return entity.$data[name];
364
354
  }
@@ -372,11 +362,11 @@ export default class Entity<T extends EntityData = EntityData>
372
362
  name.substring(0, 1) === '$'
373
363
  ) {
374
364
  if (name === 'tags' || name === 'cdate' || name === 'mdate') {
375
- this.$referenceWake();
365
+ this.$check();
376
366
  }
377
367
  (entity as any)[name] = value;
378
368
  } else {
379
- this.$referenceWake();
369
+ this.$check();
380
370
  (entity.$data as any)[name] = value;
381
371
  }
382
372
  return true;
@@ -386,7 +376,7 @@ export default class Entity<T extends EntityData = EntityData>
386
376
  if (name in entity) {
387
377
  return delete (entity as any)[name];
388
378
  } else if (name in entity.$data) {
389
- this.$referenceWake();
379
+ this.$check();
390
380
  return delete entity.$data[name];
391
381
  }
392
382
  return true;
@@ -407,11 +397,11 @@ export default class Entity<T extends EntityData = EntityData>
407
397
  name.substring(0, 1) === '$'
408
398
  ) {
409
399
  if (name === 'tags' || name === 'cdate' || name === 'mdate') {
410
- this.$referenceWake();
400
+ this.$check();
411
401
  }
412
402
  Object.defineProperty(entity, name, descriptor);
413
403
  } else {
414
- this.$referenceWake();
404
+ this.$check();
415
405
  Object.defineProperty(entity.$data, name, descriptor);
416
406
  }
417
407
  return true;
@@ -424,17 +414,17 @@ export default class Entity<T extends EntityData = EntityData>
424
414
  name.substring(0, 1) === '$'
425
415
  ) {
426
416
  if (name === 'tags' || name === 'cdate' || name === 'mdate') {
427
- this.$referenceWake();
417
+ this.$check();
428
418
  }
429
419
  return Object.getOwnPropertyDescriptor(entity, name);
430
420
  } else {
431
- this.$referenceWake();
421
+ this.$check();
432
422
  return Object.getOwnPropertyDescriptor(entity.$data, name);
433
423
  }
434
424
  },
435
425
 
436
426
  ownKeys: (entity: Entity) => {
437
- this.$referenceWake();
427
+ this.$check();
438
428
  return Object.getOwnPropertyNames(entity).concat(
439
429
  Object.getOwnPropertyNames(entity.$data)
440
430
  );
@@ -458,8 +448,8 @@ export default class Entity<T extends EntityData = EntityData>
458
448
  return entity;
459
449
  }
460
450
 
461
- public static factorySync(guid?: string) {
462
- return new this(guid);
451
+ public static factorySync() {
452
+ return new this();
463
453
  }
464
454
 
465
455
  public static factoryReference(reference: EntityReference) {
@@ -490,7 +480,7 @@ export default class Entity<T extends EntityData = EntityData>
490
480
  }
491
481
 
492
482
  public $addTag(...tags: string[]) {
493
- this.$referenceWake();
483
+ this.$check();
494
484
 
495
485
  if (tags.length < 1) {
496
486
  return;
@@ -499,7 +489,7 @@ export default class Entity<T extends EntityData = EntityData>
499
489
  }
500
490
 
501
491
  public $arraySearch(array: any[], strict = false) {
502
- this.$referenceWake();
492
+ this.$check();
503
493
 
504
494
  if (!Array.isArray(array)) {
505
495
  return -1;
@@ -514,7 +504,7 @@ export default class Entity<T extends EntityData = EntityData>
514
504
  }
515
505
 
516
506
  public $clearCache() {
517
- this.$referenceWake();
507
+ this.$check();
518
508
 
519
509
  this.$putData(this.$getData(), this.$getSData());
520
510
  }
@@ -524,13 +514,13 @@ export default class Entity<T extends EntityData = EntityData>
524
514
  }
525
515
 
526
516
  public async $delete(): Promise<boolean> {
527
- this.$referenceWake();
517
+ this.$check();
528
518
 
529
519
  return await this.$nymph.deleteEntity(this);
530
520
  }
531
521
 
532
522
  public $equals(object: any) {
533
- this.$referenceWake();
523
+ this.$check();
534
524
 
535
525
  if (!(object instanceof Entity)) {
536
526
  return false;
@@ -557,7 +547,7 @@ export default class Entity<T extends EntityData = EntityData>
557
547
  }
558
548
 
559
549
  public $getData(includeSData = false) {
560
- this.$referenceWake();
550
+ this.$check();
561
551
 
562
552
  if (includeSData) {
563
553
  // Access all the serialized properties to initialize them.
@@ -569,30 +559,56 @@ export default class Entity<T extends EntityData = EntityData>
569
559
  }
570
560
 
571
561
  public $getSData() {
572
- this.$referenceWake();
562
+ this.$check();
573
563
 
574
564
  return this.$sdata;
575
565
  }
576
566
 
577
567
  public $getOriginalAcValues() {
578
- this.$referenceWake();
579
-
580
- return (
581
- this.$originalAcValues ?? {
582
- user: this.$data.user,
583
- group: this.$data.group,
584
- acUser: this.$data.acUser,
585
- acGroup: this.$data.acGroup,
586
- acOther: this.$data.acOther,
587
- acRead: this.$data.acRead,
588
- acWrite: this.$data.acWrite,
589
- acFull: this.$data.acFull,
590
- }
591
- );
568
+ this.$check();
569
+
570
+ return this.$originalAcValues ?? this.$getCurrentAcValues();
571
+ }
572
+
573
+ public $getCurrentAcValues() {
574
+ this.$check();
575
+
576
+ return {
577
+ user: this.$getAcUid(),
578
+ group: this.$getAcGid(),
579
+ acUser: this.$data.acUser,
580
+ acGroup: this.$data.acGroup,
581
+ acOther: this.$data.acOther,
582
+ acRead: this.$getAcReadIds(),
583
+ acWrite: this.$getAcWriteIds(),
584
+ acFull: this.$getAcFullIds(),
585
+ };
586
+ }
587
+
588
+ public $getAcUid() {
589
+ return this.$data.user?.guid as string | null;
590
+ }
591
+ public $getAcGid() {
592
+ return this.$data.group?.guid as string | null;
593
+ }
594
+ public $getAcReadIds() {
595
+ return this.$data.acRead?.map((entity: EntityInterface) => entity.guid) as
596
+ | string[]
597
+ | null;
598
+ }
599
+ public $getAcWriteIds() {
600
+ return this.$data.acWrite?.map((entity: EntityInterface) => entity.guid) as
601
+ | string[]
602
+ | null;
603
+ }
604
+ public $getAcFullIds() {
605
+ return this.$data.acFull?.map((entity: EntityInterface) => entity.guid) as
606
+ | string[]
607
+ | null;
592
608
  }
593
609
 
594
610
  public $getValidatable() {
595
- this.$referenceWake();
611
+ this.$check();
596
612
 
597
613
  // Access all the serialized properties to initialize them.
598
614
  for (const key in this.$sdata) {
@@ -608,13 +624,13 @@ export default class Entity<T extends EntityData = EntityData>
608
624
  }
609
625
 
610
626
  public $getTags() {
611
- this.$referenceWake();
627
+ this.$check();
612
628
 
613
629
  return this.tags;
614
630
  }
615
631
 
616
632
  public $hasTag(...tags: string[]) {
617
- this.$referenceWake();
633
+ this.$check();
618
634
 
619
635
  if (!tags.length) {
620
636
  return false;
@@ -640,7 +656,7 @@ export default class Entity<T extends EntityData = EntityData>
640
656
  return this.guid === object.guid;
641
657
  }
642
658
 
643
- this.$referenceWake();
659
+ this.$check();
644
660
  if (typeof object.$getData !== 'function') {
645
661
  return false;
646
662
  } else {
@@ -656,8 +672,7 @@ export default class Entity<T extends EntityData = EntityData>
656
672
  }
657
673
 
658
674
  public $jsonAcceptData(input: EntityJson, allowConflict = false) {
659
- // TODO: Do this without causing everything to become unserialized.
660
- this.$referenceWake();
675
+ this.$check();
661
676
 
662
677
  if (this.guid != input.guid) {
663
678
  throw new EntityConflictError(
@@ -709,7 +724,13 @@ export default class Entity<T extends EntityData = EntityData>
709
724
  if (
710
725
  ((this.constructor as typeof Entity).class !== 'User' &&
711
726
  (this.constructor as typeof Entity).class !== 'Group') ||
712
- !this.$nymph.tilmeld.gatekeeper('tilmeld/admin')
727
+ !(this.$nymph.tilmeld as any).currentUser ||
728
+ (!(this.$nymph.tilmeld as any).currentUser.abilities?.includes(
729
+ 'tilmeld/admin'
730
+ ) &&
731
+ !(this.$nymph.tilmeld as any).currentUser.abilities?.includes(
732
+ 'system/admin'
733
+ ))
713
734
  ) {
714
735
  protectedProps.push('user');
715
736
  protectedProps.push('group');
@@ -746,7 +767,7 @@ export default class Entity<T extends EntityData = EntityData>
746
767
  }
747
768
 
748
769
  public $jsonAcceptPatch(patch: EntityPatch, allowConflict = false) {
749
- this.$referenceWake();
770
+ this.$check();
750
771
 
751
772
  if (this.guid != patch.guid) {
752
773
  throw new EntityConflictError(
@@ -773,7 +794,13 @@ export default class Entity<T extends EntityData = EntityData>
773
794
  if (
774
795
  ((this.constructor as typeof Entity).class !== 'User' &&
775
796
  (this.constructor as typeof Entity).class !== 'Group') ||
776
- !this.$nymph.tilmeld.gatekeeper('tilmeld/admin')
797
+ !(this.$nymph.tilmeld as any).currentUser ||
798
+ (!(this.$nymph.tilmeld as any).currentUser.abilities?.includes(
799
+ 'tilmeld/admin'
800
+ ) &&
801
+ !(this.$nymph.tilmeld as any).currentUser.abilities?.includes(
802
+ 'system/admin'
803
+ ))
777
804
  ) {
778
805
  protectedProps.push('user');
779
806
  protectedProps.push('group');
@@ -832,7 +859,7 @@ export default class Entity<T extends EntityData = EntityData>
832
859
  }
833
860
 
834
861
  public $putData(data: EntityData, sdata?: SerializedEntityData) {
835
- this.$referenceWake();
862
+ this.$check();
836
863
 
837
864
  const mySdata = sdata ?? this.$getSData();
838
865
  for (const name in data) {
@@ -851,7 +878,7 @@ export default class Entity<T extends EntityData = EntityData>
851
878
  this.$sdata = mySdata;
852
879
  // Set original AC values if not set..
853
880
  if (this.$originalAcValues == null) {
854
- this.$originalAcValues = this.$getOriginalAcValues();
881
+ this.$originalAcValues = this.$getCurrentAcValues();
855
882
  }
856
883
  }
857
884
 
@@ -883,38 +910,124 @@ export default class Entity<T extends EntityData = EntityData>
883
910
  this.$sleepingReference = reference;
884
911
  }
885
912
 
913
+ /**
914
+ * Check if this is a sleeping reference and throw an error if so.
915
+ */
916
+ protected $check() {
917
+ if (this.$isASleepingReference || this.$sleepingReference != null) {
918
+ throw new EntityIsSleepingReferenceError(
919
+ 'This entity is in a sleeping reference state. You must use .$wake() to wake it.'
920
+ );
921
+ }
922
+ }
923
+
924
+ /**
925
+ * Check if this is a sleeping reference.
926
+ */
927
+ public $asleep() {
928
+ return this.$isASleepingReference || this.$sleepingReference != null;
929
+ }
930
+
886
931
  /**
887
932
  * Wake from a sleeping reference.
888
- *
889
- * @returns True on success, false on failure.
890
933
  */
891
- protected $referenceWake() {
934
+ public $wake() {
892
935
  if (!this.$isASleepingReference || this.$sleepingReference == null) {
893
- return true;
936
+ this.$wakePromise = null;
937
+ return Promise.resolve(this);
894
938
  }
895
- const EntityClass = this.$nymph.getEntityClass(this.$sleepingReference[2]);
896
- const entity = this.$nymph.driver.getEntitySync(
897
- {
898
- class: EntityClass,
899
- skipAc: this.$skipAc,
900
- },
901
- { type: '&', guid: this.$sleepingReference[1] }
902
- );
903
- if (entity == null) {
904
- return false;
939
+ if (this.$sleepingReference?.[1] == null) {
940
+ throw new InvalidStateError(
941
+ 'Tried to wake a sleeping reference with no GUID.'
942
+ );
905
943
  }
906
- this.$isASleepingReference = false;
907
- this.$sleepingReference = null;
908
- this.guid = entity.guid;
909
- this.tags = entity.tags;
910
- this.cdate = entity.cdate;
911
- this.mdate = entity.mdate;
912
- this.$putData(entity.$getData(), entity.$getSData());
913
- return true;
944
+ if (!this.$wakePromise) {
945
+ const EntityClass = this.$nymph.getEntityClass(
946
+ this.$sleepingReference[2]
947
+ );
948
+ this.$wakePromise = this.$nymph
949
+ .getEntity(
950
+ {
951
+ class: EntityClass,
952
+ skipAc: this.$skipAc,
953
+ },
954
+ { type: '&', guid: this.$sleepingReference[1] }
955
+ )
956
+ .then((entity) => {
957
+ if (entity == null || entity.guid == null) {
958
+ return Promise.reject(
959
+ new InvalidStateError(
960
+ 'The sleeping reference could not be retrieved.'
961
+ )
962
+ );
963
+ }
964
+ this.$isASleepingReference = false;
965
+ this.$sleepingReference = null;
966
+ this.guid = entity.guid;
967
+ this.tags = entity.tags;
968
+ this.cdate = entity.cdate;
969
+ this.mdate = entity.mdate;
970
+ this.$putData(entity.$getData(), entity.$getSData());
971
+
972
+ return this;
973
+ })
974
+ .finally(() => {
975
+ this.$wakePromise = null;
976
+ });
977
+ }
978
+ return this.$wakePromise;
979
+ }
980
+
981
+ public $wakeAll(level?: number) {
982
+ return new Promise((resolve, reject) => {
983
+ // Run this once this entity is wake.
984
+ const wakeProps = () => {
985
+ let newLevel;
986
+ // If level is undefined, keep going forever, otherwise, stop once we've
987
+ // gone deep enough.
988
+ if (level !== undefined) {
989
+ newLevel = level - 1;
990
+ }
991
+ if (newLevel !== undefined && newLevel < 0) {
992
+ resolve(this);
993
+ return;
994
+ }
995
+ const promises = [];
996
+ // Go through data looking for entities to wake.
997
+ for (let [key, value] of Object.entries(this.$data)) {
998
+ if (value instanceof Entity && value.$isASleepingReference) {
999
+ promises.push(value.$wakeAll(newLevel));
1000
+ } else if (Array.isArray(value)) {
1001
+ for (let i = 0; i < value.length; i++) {
1002
+ if (
1003
+ value[i] instanceof Entity &&
1004
+ value[i].$isASleepingReference
1005
+ ) {
1006
+ promises.push(value[i].$wakeAll(newLevel));
1007
+ }
1008
+ }
1009
+ }
1010
+ }
1011
+ if (promises.length) {
1012
+ Promise.all(promises).then(
1013
+ () => resolve(this),
1014
+ (errObj) => reject(errObj)
1015
+ );
1016
+ } else {
1017
+ resolve(this);
1018
+ }
1019
+ };
1020
+
1021
+ if (this.$isASleepingReference) {
1022
+ this.$wake().then(wakeProps, (errObj) => reject(errObj));
1023
+ } else {
1024
+ wakeProps();
1025
+ }
1026
+ }) as Promise<Entity<T>>;
914
1027
  }
915
1028
 
916
1029
  public async $refresh() {
917
- this.$referenceWake();
1030
+ await this.$wake();
918
1031
 
919
1032
  if (this.guid == null) {
920
1033
  return false;
@@ -940,13 +1053,13 @@ export default class Entity<T extends EntityData = EntityData>
940
1053
  }
941
1054
 
942
1055
  public $removeTag(...tags: string[]) {
943
- this.$referenceWake();
1056
+ this.$check();
944
1057
 
945
1058
  this.tags = difference(this.tags, tags);
946
1059
  }
947
1060
 
948
1061
  public async $save(): Promise<boolean> {
949
- this.$referenceWake();
1062
+ await this.$wake();
950
1063
 
951
1064
  return await this.$nymph.saveEntity(this);
952
1065
  }
@@ -376,10 +376,13 @@ export interface TilmeldInterface {
376
376
  response: any;
377
377
  init(nymph: Nymph): void;
378
378
  clone(): TilmeldInterface;
379
- gatekeeper(ability?: string): boolean;
380
- authenticate(): void;
379
+ gatekeeper(ability?: string): Promise<boolean>;
380
+ authenticate(): Promise<boolean>;
381
381
  clearSession(): void;
382
382
  extractToken(token: string): Promise<any>;
383
383
  fillSession(user: any): void;
384
- checkClientUIDPermissions(name: string, type?: TilmeldAccessLevels): boolean;
384
+ checkClientUIDPermissions(
385
+ name: string,
386
+ type?: TilmeldAccessLevels
387
+ ): Promise<boolean>;
385
388
  }
@@ -102,30 +102,6 @@ export default abstract class NymphDriver {
102
102
  options?: Options<T>,
103
103
  ...selectors: Selector[]
104
104
  ): Promise<ReturnType<T['factorySync']>[] | string[] | number>;
105
- protected abstract getEntitiesSync<
106
- T extends EntityConstructor = EntityConstructor
107
- >(
108
- options: Options<T> & { return: 'count' },
109
- ...selectors: Selector[]
110
- ): number;
111
- protected abstract getEntitiesSync<
112
- T extends EntityConstructor = EntityConstructor
113
- >(
114
- options: Options<T> & { return: 'guid' },
115
- ...selectors: Selector[]
116
- ): string[];
117
- protected abstract getEntitiesSync<
118
- T extends EntityConstructor = EntityConstructor
119
- >(
120
- options?: Options<T>,
121
- ...selectors: Selector[]
122
- ): ReturnType<T['factorySync']>[];
123
- protected abstract getEntitiesSync<
124
- T extends EntityConstructor = EntityConstructor
125
- >(
126
- options?: Options<T>,
127
- ...selectors: Selector[]
128
- ): ReturnType<T['factorySync']>[] | string[] | number;
129
105
  abstract getUID(name: string): Promise<number | null>;
130
106
  abstract import(filename: string): Promise<boolean>;
131
107
  abstract newUID(name: string): Promise<number | null>;
@@ -718,63 +694,6 @@ export default abstract class NymphDriver {
718
694
  return queryParts;
719
695
  }
720
696
 
721
- /**
722
- * Get the first entity to match all options/selectors, synchronously.
723
- *
724
- * This should really only be used internally by the Entity class. It's a bad
725
- * idea to get entities synchronously. The Entity class uses this to load
726
- * sleeping references.
727
- *
728
- * @param options The options.
729
- * @param selectors Unlimited optional selectors to search for, or a single GUID. If none are given, all entities are searched for the given options.
730
- * @returns An entity, or null on failure or nothing found.
731
- */
732
- public getEntitySync<T extends EntityConstructor = EntityConstructor>(
733
- options: Options<T> & { return: 'count' },
734
- ...selectors: Selector[]
735
- ): number;
736
- public getEntitySync<T extends EntityConstructor = EntityConstructor>(
737
- options: Options<T> & { return: 'guid' },
738
- ...selectors: Selector[]
739
- ): string | null;
740
- public getEntitySync<T extends EntityConstructor = EntityConstructor>(
741
- options: Options<T>,
742
- ...selectors: Selector[]
743
- ): ReturnType<T['factorySync']> | null;
744
- public getEntitySync<T extends EntityConstructor = EntityConstructor>(
745
- options: Options<T> & { return: 'count' },
746
- guid: string
747
- ): number;
748
- public getEntitySync<T extends EntityConstructor = EntityConstructor>(
749
- options: Options<T> & { return: 'guid' },
750
- guid: string
751
- ): string | null;
752
- public getEntitySync<T extends EntityConstructor = EntityConstructor>(
753
- options: Options<T>,
754
- guid: string
755
- ): ReturnType<T['factorySync']> | null;
756
- public getEntitySync<T extends EntityConstructor = EntityConstructor>(
757
- options: Options<T> = {},
758
- ...selectors: Selector[] | string[]
759
- ): ReturnType<T['factorySync']> | string | number | null {
760
- // Set up options and selectors.
761
- if (typeof selectors[0] === 'string') {
762
- selectors = [{ type: '&', guid: selectors[0] }];
763
- }
764
- options.limit = 1;
765
- const entities = this.getEntitiesSync(
766
- options,
767
- ...(selectors as Selector[])
768
- );
769
- if (options.return === 'count') {
770
- return entities as unknown as number;
771
- }
772
- if (!entities || !entities.length) {
773
- return null;
774
- }
775
- return entities[0];
776
- }
777
-
778
697
  protected getEntitesRowLike<T extends EntityConstructor = EntityConstructor>(
779
698
  options: Options<T> & { return: 'count' },
780
699
  selectors: Selector[],