@nymphjs/nymph 1.0.0-beta.7 → 1.0.0-beta.70

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 (65) hide show
  1. package/CHANGELOG.md +320 -0
  2. package/README.md +13 -21
  3. package/dist/Entity.d.ts +269 -7
  4. package/dist/Entity.js +491 -105
  5. package/dist/Entity.js.map +1 -1
  6. package/dist/Entity.test.js +39 -17
  7. package/dist/Entity.test.js.map +1 -1
  8. package/dist/Entity.types.d.ts +225 -19
  9. package/dist/Nymph.d.ts +423 -11
  10. package/dist/Nymph.js +685 -176
  11. package/dist/Nymph.js.map +1 -1
  12. package/dist/Nymph.types.d.ts +31 -7
  13. package/dist/Nymph.types.js +2 -1
  14. package/dist/Nymph.types.js.map +1 -1
  15. package/dist/conf/d.d.ts +26 -0
  16. package/dist/conf/defaults.js +22 -0
  17. package/dist/conf/defaults.js.map +1 -1
  18. package/dist/driver/NymphDriver.d.ts +129 -38
  19. package/dist/driver/NymphDriver.js +264 -131
  20. package/dist/driver/NymphDriver.js.map +1 -1
  21. package/dist/driver/testArtifacts.d.ts +1 -1
  22. package/dist/driver/testArtifacts.js +336 -42
  23. package/dist/driver/testArtifacts.js.map +1 -1
  24. package/dist/errors/EntityInvalidDataError.d.ts +6 -0
  25. package/dist/errors/EntityInvalidDataError.js +7 -1
  26. package/dist/errors/EntityInvalidDataError.js.map +1 -1
  27. package/dist/errors/EntityUniqueConstraintError.d.ts +3 -0
  28. package/dist/errors/EntityUniqueConstraintError.js +11 -0
  29. package/dist/errors/EntityUniqueConstraintError.js.map +1 -0
  30. package/dist/errors/InvalidStateError.d.ts +3 -0
  31. package/dist/errors/InvalidStateError.js +11 -0
  32. package/dist/errors/InvalidStateError.js.map +1 -0
  33. package/dist/errors/QueryFailedError.js +1 -0
  34. package/dist/errors/QueryFailedError.js.map +1 -1
  35. package/dist/errors/index.d.ts +2 -0
  36. package/dist/errors/index.js +2 -0
  37. package/dist/errors/index.js.map +1 -1
  38. package/dist/testArtifacts.d.ts +17 -5
  39. package/dist/testArtifacts.js +31 -27
  40. package/dist/testArtifacts.js.map +1 -1
  41. package/dist/testMocks.d.ts +15 -10
  42. package/dist/testMocks.js +37 -13
  43. package/dist/testMocks.js.map +1 -1
  44. package/dist/utils.d.ts +1 -1
  45. package/dist/utils.js +21 -5
  46. package/dist/utils.js.map +1 -1
  47. package/package.json +16 -14
  48. package/src/Entity.test.ts +32 -11
  49. package/src/Entity.ts +423 -134
  50. package/src/Entity.types.ts +32 -66
  51. package/src/Nymph.ts +618 -195
  52. package/src/Nymph.types.ts +97 -26
  53. package/src/conf/d.ts +8 -0
  54. package/src/conf/defaults.ts +24 -0
  55. package/src/driver/NymphDriver.ts +281 -311
  56. package/src/driver/testArtifacts.ts +384 -173
  57. package/src/errors/EntityUniqueConstraintError.ts +6 -0
  58. package/src/errors/InvalidStateError.ts +6 -0
  59. package/src/errors/index.ts +4 -0
  60. package/src/nymphJoiProps.ts +2 -2
  61. package/src/testArtifacts.ts +18 -19
  62. package/src/testMocks.ts +64 -32
  63. package/src/utils.ts +22 -8
  64. package/tsconfig.json +3 -3
  65. package/typedoc.json +4 -0
@@ -3,18 +3,21 @@ import strtotime from 'locutus/php/datetime/strtotime';
3
3
  import { guid } from '@nymphjs/guid';
4
4
 
5
5
  import type Nymph from '../Nymph';
6
+ import { EntityUniqueConstraintError } from '../errors';
6
7
  import {
7
8
  TestBModel as TestBModelClass,
8
9
  TestModel as TestModelClass,
9
10
  TestModelData,
11
+ TestEmptyModel as TestEmptyModelClass,
10
12
  } from '../testArtifacts';
11
13
 
12
- export function QueriesTest(
14
+ export function EntitiesTest(
13
15
  nymph: Nymph,
14
- it: (name: string, fn: () => void) => void
16
+ it: (name: string, fn: () => void) => void,
15
17
  ) {
16
18
  const TestModel = nymph.addEntityClass(TestModelClass);
17
19
  const TestBModel = nymph.addEntityClass(TestBModelClass);
20
+ const TestEmptyModel = nymph.addEntityClass(TestEmptyModelClass);
18
21
 
19
22
  let testEntity: TestModelClass & TestModelData;
20
23
  let testGuid: string;
@@ -39,7 +42,10 @@ export function QueriesTest(
39
42
 
40
43
  This one's email address is nice_hat-wednesday+newyork@im-a-hat.hat.
41
44
  This one's phone number is (555) 555-1818.
42
- This one's zip code is 92064.`;
45
+ This one's zip code is 92064.
46
+ This one's favorite emojis are 🔥❤️😊😂⭐🤔
47
+
48
+ These hats are absolutely fantastic.`;
43
49
  testEntity.number = 30;
44
50
  testEntity.numberString = '30';
45
51
  testEntity.timestamp = Date.now();
@@ -59,18 +65,10 @@ This one's zip code is 92064.`;
59
65
  entityReferenceTest.test = 'good';
60
66
  expect(await entityReferenceTest.$save()).toEqual(true);
61
67
 
62
- // Test synchronous getEntity.
63
- testEntity = nymph.driver.getEntitySync(
64
- { class: TestModel },
65
- testGuid
66
- ) as TestModelClass & TestModelData;
67
- expect(testEntity).toBeInstanceOf(TestModel);
68
- expect(testEntity.guid).toEqual(testGuid);
69
-
70
68
  // Test asynchronous getEntity.
71
69
  testEntity = (await nymph.getEntity(
72
70
  { class: TestModel },
73
- testGuid
71
+ testGuid,
74
72
  )) as TestModelClass & TestModelData;
75
73
  expect(testEntity).toBeInstanceOf(TestModel);
76
74
  expect(testEntity.guid).toEqual(testGuid);
@@ -84,6 +82,8 @@ This one's zip code is 92064.`;
84
82
  for (let i = 0; i < 100; i++) {
85
83
  const testEntity = await TestModel.factory();
86
84
  testEntity.name = `Multi Test ${i}`;
85
+ // Reverse the number for sort testing.
86
+ testEntity.number = 100 - i;
87
87
  testEntity.$removeTag('test');
88
88
  testEntity.$addTag('multiTest');
89
89
  expect(await testEntity.$save()).toEqual(true);
@@ -94,20 +94,36 @@ This one's zip code is 92064.`;
94
94
  }
95
95
 
96
96
  it('delete old test data', async () => {
97
- let all = await nymph.getEntities({ class: TestModel });
98
- expect(Array.isArray(all)).toEqual(true);
99
- for (const cur of all) {
97
+ let amodels = await nymph.getEntities({ class: TestModel });
98
+ expect(Array.isArray(amodels)).toEqual(true);
99
+ for (const cur of amodels) {
100
100
  expect(await cur.$delete()).toEqual(true);
101
101
  }
102
102
 
103
- all = await nymph.getEntities({ class: TestModel });
104
- expect(all.length).toEqual(0);
103
+ amodels = await nymph.getEntities({ class: TestModel });
104
+ expect(amodels.length).toEqual(0);
105
+
106
+ let bmodels = await nymph.getEntities({ class: TestBModel });
107
+ expect(Array.isArray(bmodels)).toEqual(true);
108
+ for (const cur of bmodels) {
109
+ expect(await cur.$delete()).toEqual(true);
110
+ }
111
+
112
+ bmodels = await nymph.getEntities({ class: TestBModel });
113
+ expect(bmodels.length).toEqual(0);
105
114
  });
106
115
 
107
116
  it('create entity', async () => {
108
117
  await createTestEntities();
109
118
  });
110
119
 
120
+ it("doesn't create empty entity", async () => {
121
+ const testEntity = await TestEmptyModel.factory();
122
+
123
+ expect(await testEntity.$save()).toBeFalsy();
124
+ expect(testEntity.guid).toBeNull();
125
+ });
126
+
111
127
  it('update mdate on save', async () => {
112
128
  await createTestEntities();
113
129
 
@@ -150,7 +166,7 @@ This one's zip code is 92064.`;
150
166
 
151
167
  if (!(await transaction.inTransaction())) {
152
168
  console.log(
153
- 'This Nymph driver or database seems to not support transactions. Skipping transaction tests.'
169
+ 'This Nymph driver or database seems to not support transactions. Skipping transaction tests.',
154
170
  );
155
171
  await transaction.rollback('test');
156
172
  return;
@@ -181,7 +197,7 @@ This one's zip code is 92064.`;
181
197
  expect(await testEntity.$delete()).toEqual(true);
182
198
  const resultEntity = await transaction.getEntity(
183
199
  { class: TestModel },
184
- testGuid
200
+ testGuid,
185
201
  );
186
202
  expect(resultEntity).toBeNull();
187
203
 
@@ -194,13 +210,13 @@ This one's zip code is 92064.`;
194
210
  // Verify it's back.
195
211
  testEntity = (await transaction.getEntity(
196
212
  { class: TestModel },
197
- testGuid
213
+ testGuid,
198
214
  )) as TestModelClass & TestModelData;
199
215
 
200
216
  expect(testEntity.guid).toEqual(testGuid);
201
217
 
202
- // Start a new transaction.
203
- transaction = await nymph.startTransaction('test');
218
+ // Start a new transaction with a dot in the name.
219
+ transaction = await nymph.startTransaction('test.1');
204
220
  testEntity.$nymph = transaction;
205
221
 
206
222
  // Verify in a transaction.
@@ -211,7 +227,7 @@ This one's zip code is 92064.`;
211
227
  expect(await testEntity.$save()).toEqual(true);
212
228
 
213
229
  // Commit the transaction.
214
- await transaction.commit('test');
230
+ await transaction.commit('test.1');
215
231
  testEntity.$nymph = nymph;
216
232
 
217
233
  // Verify not in a transaction.
@@ -240,7 +256,7 @@ This one's zip code is 92064.`;
240
256
  limit: 1,
241
257
  sort: 'cdate',
242
258
  },
243
- { type: '&', tag: 'test' }
259
+ { type: '&', tag: 'test' },
244
260
  );
245
261
  expect(resultEntities.length).toEqual(1);
246
262
  expect(testEntity.$is(resultEntities[0])).toEqual(true);
@@ -252,7 +268,7 @@ This one's zip code is 92064.`;
252
268
  // Retrieving entity by GUID and tags...
253
269
  const resultEntity = await nymph.getEntity(
254
270
  { class: TestModel },
255
- { type: '&', guid: testGuid, tag: 'test' }
271
+ { type: '&', guid: testGuid, tag: 'test' },
256
272
  );
257
273
  expect(testEntity.$is(resultEntity)).toEqual(true);
258
274
  });
@@ -263,7 +279,7 @@ This one's zip code is 92064.`;
263
279
  // Retrieving entity by GUID and tags...
264
280
  const resultEntity = await nymph.getEntity(
265
281
  { class: TestModel },
266
- { type: '|', guid: [testGuid, guid()] }
282
+ { type: '|', guid: [testGuid, guid()] },
267
283
  );
268
284
  expect(testEntity.$is(resultEntity)).toEqual(true);
269
285
  });
@@ -274,7 +290,7 @@ This one's zip code is 92064.`;
274
290
  // Retrieving entity by GUID and tags...
275
291
  const resultEntity = await nymph.getEntity(
276
292
  { class: TestModel },
277
- { type: '|', guid: [guid(), guid()] }
293
+ { type: '|', guid: [guid(), guid()] },
278
294
  );
279
295
  expect(testEntity.$is(resultEntity)).toEqual(false);
280
296
  });
@@ -285,7 +301,7 @@ This one's zip code is 92064.`;
285
301
  // Retrieving entity by !GUID...
286
302
  const resultEntity = await nymph.getEntities(
287
303
  { class: TestModel },
288
- { type: '&', '!guid': guid(), tag: 'test' }
304
+ { type: '&', '!guid': guid(), tag: 'test' },
289
305
  );
290
306
  expect(testEntity.$inArray(resultEntity)).toEqual(true);
291
307
  });
@@ -296,7 +312,7 @@ This one's zip code is 92064.`;
296
312
  // Retrieving entity by !tags...
297
313
  const resultEntity = await nymph.getEntities(
298
314
  { class: TestModel },
299
- { type: '&', guid: testGuid, '!tag': ['barbecue', 'pickles'] }
315
+ { type: '&', guid: testGuid, '!tag': ['barbecue', 'pickles'] },
300
316
  );
301
317
  expect(testEntity.$inArray(resultEntity)).toEqual(true);
302
318
  });
@@ -307,7 +323,7 @@ This one's zip code is 92064.`;
307
323
  // Testing GUID and wrong tags...
308
324
  const resultEntity = await nymph.getEntity(
309
325
  { class: TestModel },
310
- { type: '&', guid: testGuid, tag: ['pickles'] }
326
+ { type: '&', guid: testGuid, tag: ['pickles'] },
311
327
  );
312
328
  expect(resultEntity).toBeNull();
313
329
  });
@@ -318,7 +334,7 @@ This one's zip code is 92064.`;
318
334
  // Retrieving entity by tags...
319
335
  const resultEntity = await nymph.getEntities(
320
336
  { class: TestModel },
321
- { type: '&', tag: 'test' }
337
+ { type: '&', tag: 'test' },
322
338
  );
323
339
  expect(testEntity.$inArray(resultEntity)).toEqual(true);
324
340
  });
@@ -329,7 +345,7 @@ This one's zip code is 92064.`;
329
345
  // Testing wrong tags...
330
346
  const resultEntity = await nymph.getEntities(
331
347
  { class: TestModel },
332
- { type: '&', tag: 'pickles' }
348
+ { type: '&', tag: 'pickles' },
333
349
  );
334
350
  expect(testEntity.$inArray(resultEntity)).toEqual(false);
335
351
  });
@@ -340,7 +356,7 @@ This one's zip code is 92064.`;
340
356
  // Retrieving entity by tags inclusively...
341
357
  const resultEntity = await nymph.getEntities(
342
358
  { class: TestModel },
343
- { type: '|', tag: ['pickles', 'test', 'barbecue'] }
359
+ { type: '|', tag: ['pickles', 'test', 'barbecue'] },
344
360
  );
345
361
  expect(testEntity.$inArray(resultEntity)).toEqual(true);
346
362
  });
@@ -351,7 +367,7 @@ This one's zip code is 92064.`;
351
367
  // Testing wrong inclusive tags...
352
368
  const resultEntity = await nymph.getEntities(
353
369
  { class: TestModel },
354
- { type: '|', tag: ['pickles', 'barbecue'] }
370
+ { type: '|', tag: ['pickles', 'barbecue'] },
355
371
  );
356
372
  expect(testEntity.$inArray(resultEntity)).toEqual(false);
357
373
  });
@@ -363,7 +379,7 @@ This one's zip code is 92064.`;
363
379
  const resultEntity = await nymph.getEntities(
364
380
  { class: TestModel },
365
381
  { type: '&', tag: 'test' },
366
- { type: '|', tag: ['pickles', 'test', 'barbecue'] }
382
+ { type: '|', tag: ['pickles', 'test', 'barbecue'] },
367
383
  );
368
384
  expect(testEntity.$inArray(resultEntity)).toEqual(true);
369
385
  });
@@ -375,7 +391,7 @@ This one's zip code is 92064.`;
375
391
  const resultEntity = await nymph.getEntities(
376
392
  { class: TestModel },
377
393
  { type: '&', tag: 'test' },
378
- { type: '|', tag: ['pickles', 'barbecue'] }
394
+ { type: '|', tag: ['pickles', 'barbecue'] },
379
395
  );
380
396
  expect(testEntity.$inArray(resultEntity)).toEqual(false);
381
397
  });
@@ -387,7 +403,7 @@ This one's zip code is 92064.`;
387
403
  const resultEntity = await nymph.getEntities(
388
404
  { class: TestModel },
389
405
  { type: '&', tag: 'pickles' },
390
- { type: '|', tag: ['test', 'barbecue'] }
406
+ { type: '|', tag: ['test', 'barbecue'] },
391
407
  );
392
408
  expect(testEntity.$inArray(resultEntity)).toEqual(false);
393
409
  });
@@ -398,7 +414,7 @@ This one's zip code is 92064.`;
398
414
  // Retrieving entity by defined...
399
415
  const resultEntity = await nymph.getEntities(
400
416
  { class: TestModel },
401
- { type: '&', defined: 'string' }
417
+ { type: '&', defined: 'string' },
402
418
  );
403
419
  expect(testEntity.$inArray(resultEntity)).toEqual(true);
404
420
  });
@@ -409,7 +425,7 @@ This one's zip code is 92064.`;
409
425
  // Retrieving entity by !defined...
410
426
  const resultEntity = await nymph.getEntities(
411
427
  { class: TestModel },
412
- { type: '&', tag: 'test', '!defined': 'pickles' }
428
+ { type: '&', tag: 'test', '!defined': 'pickles' },
413
429
  );
414
430
  expect(testEntity.$inArray(resultEntity)).toEqual(true);
415
431
  });
@@ -421,7 +437,7 @@ This one's zip code is 92064.`;
421
437
  const resultEntity = await nymph.getEntities(
422
438
  { class: TestModel },
423
439
  { type: '!&', defined: 'pickles' },
424
- { type: '&', tag: 'test' }
440
+ { type: '&', tag: 'test' },
425
441
  );
426
442
  expect(testEntity.$inArray(resultEntity)).toEqual(true);
427
443
  });
@@ -432,7 +448,7 @@ This one's zip code is 92064.`;
432
448
  // Retrieving entity by equal...
433
449
  const resultEntity = await nymph.getEntities(
434
450
  { class: TestModel },
435
- { type: '&', equal: ['string', 'test'] }
451
+ { type: '&', equal: ['string', 'test'] },
436
452
  );
437
453
  expect(testEntity.$inArray(resultEntity)).toEqual(true);
438
454
  });
@@ -446,7 +462,7 @@ This one's zip code is 92064.`;
446
462
  // Retrieving entity by !equal...
447
463
  const resultEntity = await nymph.getEntities(
448
464
  { class: TestModel },
449
- { type: '&', tag: 'test', '!equal': ['string', 'wrong'] }
465
+ { type: '&', tag: 'test', '!equal': ['string', 'wrong'] },
450
466
  );
451
467
  expect(testEntity.$inArray(resultEntity)).toEqual(true);
452
468
  expect(referenceEntity.$inArray(resultEntity)).toEqual(false);
@@ -458,7 +474,7 @@ This one's zip code is 92064.`;
458
474
  // Retrieving entity by like...
459
475
  const resultEntity = await nymph.getEntities(
460
476
  { class: TestModel },
461
- { type: '&', like: ['string', 't_s%'] }
477
+ { type: '&', like: ['string', 't_s%'] },
462
478
  );
463
479
  expect(testEntity.$inArray(resultEntity)).toEqual(true);
464
480
  });
@@ -472,7 +488,7 @@ This one's zip code is 92064.`;
472
488
  // Retrieving entity by !like...
473
489
  const resultEntity = await nymph.getEntities(
474
490
  { class: TestModel },
475
- { type: '&', tag: 'test', '!like': ['string', 'wr_n%'] }
491
+ { type: '&', tag: 'test', '!like': ['string', 'wr_n%'] },
476
492
  );
477
493
  expect(testEntity.$inArray(resultEntity)).toEqual(true);
478
494
  expect(referenceEntity.$inArray(resultEntity)).toEqual(false);
@@ -484,7 +500,7 @@ This one's zip code is 92064.`;
484
500
  // Retrieving entity by ilike...
485
501
  const resultEntity = await nymph.getEntities(
486
502
  { class: TestModel },
487
- { type: '&', ilike: ['string', 'T_s%'] }
503
+ { type: '&', ilike: ['string', 'T_s%'] },
488
504
  );
489
505
  expect(testEntity.$inArray(resultEntity)).toEqual(true);
490
506
  });
@@ -498,7 +514,7 @@ This one's zip code is 92064.`;
498
514
  // Retrieving entity by !ilike...
499
515
  const resultEntity = await nymph.getEntities(
500
516
  { class: TestModel },
501
- { type: '&', tag: 'test', '!ilike': ['string', 'wr_n%'] }
517
+ { type: '&', tag: 'test', '!ilike': ['string', 'wr_n%'] },
502
518
  );
503
519
  expect(testEntity.$inArray(resultEntity)).toEqual(true);
504
520
  expect(referenceEntity.$inArray(resultEntity)).toEqual(false);
@@ -510,7 +526,7 @@ This one's zip code is 92064.`;
510
526
  // Retrieving entity by like...
511
527
  const resultEntity = await nymph.getEntities(
512
528
  { class: TestModel },
513
- { type: '&', like: ['string', 'T_s%'] }
529
+ { type: '&', like: ['string', 'T_s%'] },
514
530
  );
515
531
  expect(testEntity.$inArray(resultEntity)).toEqual(false);
516
532
  });
@@ -521,7 +537,7 @@ This one's zip code is 92064.`;
521
537
  // Retrieving entity by tags and equal...
522
538
  const resultEntity = await nymph.getEntities(
523
539
  { class: TestModel },
524
- { type: '&', tag: 'test', equal: ['string', 'test'] }
540
+ { type: '&', tag: 'test', equal: ['string', 'test'] },
525
541
  );
526
542
  expect(testEntity.$inArray(resultEntity)).toEqual(true);
527
543
  });
@@ -532,7 +548,7 @@ This one's zip code is 92064.`;
532
548
  // Testing wrong tags and right equal...
533
549
  const resultEntity = await nymph.getEntities(
534
550
  { class: TestModel },
535
- { type: '&', tag: 'pickles', equal: ['string', 'test'] }
551
+ { type: '&', tag: 'pickles', equal: ['string', 'test'] },
536
552
  );
537
553
  expect(testEntity.$inArray(resultEntity)).toEqual(false);
538
554
  });
@@ -543,7 +559,7 @@ This one's zip code is 92064.`;
543
559
  // Testing right tags and wrong equal...
544
560
  const resultEntity = await nymph.getEntities(
545
561
  { class: TestModel },
546
- { type: '&', tag: 'test', equal: ['string', 'pickles'] }
562
+ { type: '&', tag: 'test', equal: ['string', 'pickles'] },
547
563
  );
548
564
  expect(testEntity.$inArray(resultEntity)).toEqual(false);
549
565
  });
@@ -554,7 +570,7 @@ This one's zip code is 92064.`;
554
570
  // Testing wrong tags and wrong equal...
555
571
  const resultEntity = await nymph.getEntities(
556
572
  { class: TestModel },
557
- { type: '&', tag: 'pickles', equal: ['string', 'pickles'] }
573
+ { type: '&', tag: 'pickles', equal: ['string', 'pickles'] },
558
574
  );
559
575
  expect(testEntity.$inArray(resultEntity)).toEqual(false);
560
576
  });
@@ -565,14 +581,14 @@ This one's zip code is 92064.`;
565
581
  // Retrieving entity by contain...
566
582
  let resultEntity = await nymph.getEntities(
567
583
  { class: TestModel },
568
- { type: '&', contain: ['array', 'values'] }
584
+ { type: '&', contain: ['array', 'values'] },
569
585
  );
570
586
  expect(testEntity.$inArray(resultEntity)).toEqual(true);
571
587
 
572
588
  // Retrieving entity by contain with full match...
573
589
  resultEntity = await nymph.getEntities(
574
590
  { class: TestModel },
575
- { type: '&', contain: ['string', 'test'] }
591
+ { type: '&', contain: ['string', 'test'] },
576
592
  );
577
593
  expect(testEntity.$inArray(resultEntity)).toEqual(true);
578
594
  });
@@ -584,7 +600,7 @@ This one's zip code is 92064.`;
584
600
  const resultEntity = await nymph.getEntities(
585
601
  { class: TestModel },
586
602
  { type: '&', tag: 'test' },
587
- { type: '!&', contain: ['array', 'pickles'] }
603
+ { type: '!&', contain: ['array', 'pickles'] },
588
604
  );
589
605
  expect(testEntity.$inArray(resultEntity)).toEqual(true);
590
606
  });
@@ -595,14 +611,14 @@ This one's zip code is 92064.`;
595
611
  // Testing wrong contain...
596
612
  let resultEntity = await nymph.getEntities(
597
613
  { class: TestModel },
598
- { type: '&', contain: ['array', 'pickles'] }
614
+ { type: '&', contain: ['array', 'pickles'] },
599
615
  );
600
616
  expect(testEntity.$inArray(resultEntity)).toEqual(false);
601
617
 
602
618
  // Testing wrong contain...
603
619
  resultEntity = await nymph.getEntities(
604
620
  { class: TestModel },
605
- { type: '&', contain: ['string', 'pickles'] }
621
+ { type: '&', contain: ['string', 'pickles'] },
606
622
  );
607
623
  expect(testEntity.$inArray(resultEntity)).toEqual(false);
608
624
  });
@@ -613,12 +629,12 @@ This one's zip code is 92064.`;
613
629
  // Retrieving entity by regex match...
614
630
  let resultEntity = await nymph.getEntities(
615
631
  { class: TestModel },
616
- { type: '&', match: ['match', '.*'] } // anything
632
+ { type: '&', match: ['match', '.*'] }, // anything
617
633
  );
618
634
  expect(testEntity.$inArray(resultEntity)).toEqual(true);
619
635
  resultEntity = await nymph.getEntities(
620
636
  { class: TestModel },
621
- { type: '&', tag: 'test', match: ['match', 'Edward McCheese'] } // a substring
637
+ { type: '&', tag: 'test', match: ['match', 'Edward McCheese'] }, // a substring
622
638
  );
623
639
  expect(testEntity.$inArray(resultEntity)).toEqual(true);
624
640
  resultEntity = await nymph.getEntities(
@@ -630,7 +646,7 @@ This one's zip code is 92064.`;
630
646
  ['string', '[0-9]'],
631
647
  ['match', 'Edward McCheese'],
632
648
  ],
633
- } // inclusive test
649
+ }, // inclusive test
634
650
  );
635
651
  expect(testEntity.$inArray(resultEntity)).toEqual(true);
636
652
  resultEntity = await nymph.getEntities(
@@ -639,7 +655,7 @@ This one's zip code is 92064.`;
639
655
  type: '&',
640
656
  tag: 'test',
641
657
  match: ['match', '[-a-zA-Z0-9+_]+@[-a-zA-Z0-9_]+.[-a-zA-Z0-9_]{2,4}'],
642
- } // a simple email
658
+ }, // a simple email
643
659
  );
644
660
  expect(testEntity.$inArray(resultEntity)).toEqual(true);
645
661
  resultEntity = await nymph.getEntities(
@@ -648,7 +664,7 @@ This one's zip code is 92064.`;
648
664
  type: '&',
649
665
  tag: 'test',
650
666
  match: ['match', '\\([0-9]{3}\\) [0-9]{3}-[0-9]{4}'],
651
- } // a phone number
667
+ }, // a phone number
652
668
  );
653
669
  expect(testEntity.$inArray(resultEntity)).toEqual(true);
654
670
  });
@@ -659,7 +675,7 @@ This one's zip code is 92064.`;
659
675
  // Retrieving entity by regex match...
660
676
  const resultEntity = await nymph.getEntities(
661
677
  { class: TestModel },
662
- { type: '&', tag: 'test', imatch: ['match', 'edward mccheese'] } // a substring
678
+ { type: '&', tag: 'test', imatch: ['match', 'edward mccheese'] }, // a substring
663
679
  );
664
680
  expect(testEntity.$inArray(resultEntity)).toEqual(true);
665
681
  });
@@ -670,12 +686,12 @@ This one's zip code is 92064.`;
670
686
  // Testing wrong regex match...
671
687
  let resultEntity = await nymph.getEntities(
672
688
  { class: TestModel },
673
- { type: '&', match: ['match', 'Q'] }
689
+ { type: '&', match: ['match', 'Q'] },
674
690
  );
675
691
  expect(testEntity.$inArray(resultEntity)).toEqual(false);
676
692
  resultEntity = await nymph.getEntities(
677
693
  { class: TestModel },
678
- { type: '&', tag: 'pickle', match: ['match', '.*'] }
694
+ { type: '&', tag: 'pickle', match: ['match', '.*'] },
679
695
  );
680
696
  expect(testEntity.$inArray(resultEntity)).toEqual(false);
681
697
  resultEntity = await nymph.getEntities(
@@ -686,7 +702,7 @@ This one's zip code is 92064.`;
686
702
  ['string', '[0-9]'],
687
703
  ['match', ',,'],
688
704
  ],
689
- }
705
+ },
690
706
  );
691
707
  expect(testEntity.$inArray(resultEntity)).toEqual(false);
692
708
  });
@@ -697,7 +713,7 @@ This one's zip code is 92064.`;
697
713
  // Retrieving entity by regex match...
698
714
  const resultEntity = await nymph.getEntities(
699
715
  { class: TestModel },
700
- { type: '&', tag: 'test', match: ['match', 'edward mccheese'] } // a substring
716
+ { type: '&', tag: 'test', match: ['match', 'edward mccheese'] }, // a substring
701
717
  );
702
718
  expect(testEntity.$inArray(resultEntity)).toEqual(false);
703
719
  });
@@ -709,7 +725,7 @@ This one's zip code is 92064.`;
709
725
  const resultEntity = await nymph.getEntities(
710
726
  { class: TestModel },
711
727
  { type: '&', tag: 'test' },
712
- { type: '|', equal: ['string', 'pickles'], match: ['string', 'test'] }
728
+ { type: '|', equal: ['string', 'pickles'], match: ['string', 'test'] },
713
729
  );
714
730
  expect(testEntity.$inArray(resultEntity)).toEqual(true);
715
731
  });
@@ -726,7 +742,7 @@ This one's zip code is 92064.`;
726
742
  ['number', 30],
727
743
  ['pickles', 100],
728
744
  ],
729
- }
745
+ },
730
746
  );
731
747
  expect(testEntity.$inArray(resultEntity)).toEqual(false);
732
748
 
@@ -739,7 +755,7 @@ This one's zip code is 92064.`;
739
755
  ['number', 31],
740
756
  ['pickles', 100],
741
757
  ],
742
- }
758
+ },
743
759
  );
744
760
  expect(testEntity.$inArray(resultEntity)).toEqual(false);
745
761
 
@@ -752,7 +768,7 @@ This one's zip code is 92064.`;
752
768
  ['number', 29],
753
769
  ['pickles', 100],
754
770
  ],
755
- }
771
+ },
756
772
  );
757
773
  expect(testEntity.$inArray(resultEntity)).toEqual(true);
758
774
 
@@ -765,7 +781,7 @@ This one's zip code is 92064.`;
765
781
  ['numberString', 30],
766
782
  ['pickles', 100],
767
783
  ],
768
- }
784
+ },
769
785
  );
770
786
  expect(testEntity.$inArray(resultEntity)).toEqual(false);
771
787
 
@@ -778,7 +794,7 @@ This one's zip code is 92064.`;
778
794
  ['numberString', 31],
779
795
  ['pickles', 100],
780
796
  ],
781
- }
797
+ },
782
798
  );
783
799
  expect(testEntity.$inArray(resultEntity)).toEqual(false);
784
800
 
@@ -791,7 +807,7 @@ This one's zip code is 92064.`;
791
807
  ['numberString', 29],
792
808
  ['pickles', 100],
793
809
  ],
794
- }
810
+ },
795
811
  );
796
812
  expect(testEntity.$inArray(resultEntity)).toEqual(true);
797
813
  });
@@ -808,7 +824,7 @@ This one's zip code is 92064.`;
808
824
  ['number', 30],
809
825
  ['pickles', 100],
810
826
  ],
811
- }
827
+ },
812
828
  );
813
829
  expect(testEntity.$inArray(resultEntity)).toEqual(true);
814
830
 
@@ -821,7 +837,7 @@ This one's zip code is 92064.`;
821
837
  ['number', 31],
822
838
  ['pickles', 100],
823
839
  ],
824
- }
840
+ },
825
841
  );
826
842
  expect(testEntity.$inArray(resultEntity)).toEqual(false);
827
843
 
@@ -834,7 +850,7 @@ This one's zip code is 92064.`;
834
850
  ['number', 29],
835
851
  ['pickles', 100],
836
852
  ],
837
- }
853
+ },
838
854
  );
839
855
  expect(testEntity.$inArray(resultEntity)).toEqual(true);
840
856
 
@@ -847,7 +863,7 @@ This one's zip code is 92064.`;
847
863
  ['numberString', 30],
848
864
  ['pickles', 100],
849
865
  ],
850
- }
866
+ },
851
867
  );
852
868
  expect(testEntity.$inArray(resultEntity)).toEqual(true);
853
869
 
@@ -860,7 +876,7 @@ This one's zip code is 92064.`;
860
876
  ['numberString', 31],
861
877
  ['pickles', 100],
862
878
  ],
863
- }
879
+ },
864
880
  );
865
881
  expect(testEntity.$inArray(resultEntity)).toEqual(false);
866
882
 
@@ -873,7 +889,7 @@ This one's zip code is 92064.`;
873
889
  ['numberString', 29],
874
890
  ['pickles', 100],
875
891
  ],
876
- }
892
+ },
877
893
  );
878
894
  expect(testEntity.$inArray(resultEntity)).toEqual(true);
879
895
  });
@@ -890,7 +906,7 @@ This one's zip code is 92064.`;
890
906
  ['number', 30],
891
907
  ['pickles', 100],
892
908
  ],
893
- }
909
+ },
894
910
  );
895
911
  expect(testEntity.$inArray(resultEntity)).toEqual(false);
896
912
 
@@ -903,7 +919,7 @@ This one's zip code is 92064.`;
903
919
  ['number', 31],
904
920
  ['pickles', 100],
905
921
  ],
906
- }
922
+ },
907
923
  );
908
924
  expect(testEntity.$inArray(resultEntity)).toEqual(true);
909
925
 
@@ -916,7 +932,7 @@ This one's zip code is 92064.`;
916
932
  ['number', 29],
917
933
  ['pickles', 100],
918
934
  ],
919
- }
935
+ },
920
936
  );
921
937
  expect(testEntity.$inArray(resultEntity)).toEqual(false);
922
938
 
@@ -929,7 +945,7 @@ This one's zip code is 92064.`;
929
945
  ['numberString', 30],
930
946
  ['pickles', 100],
931
947
  ],
932
- }
948
+ },
933
949
  );
934
950
  expect(testEntity.$inArray(resultEntity)).toEqual(false);
935
951
 
@@ -942,7 +958,7 @@ This one's zip code is 92064.`;
942
958
  ['numberString', 31],
943
959
  ['pickles', 100],
944
960
  ],
945
- }
961
+ },
946
962
  );
947
963
  expect(testEntity.$inArray(resultEntity)).toEqual(true);
948
964
 
@@ -955,7 +971,7 @@ This one's zip code is 92064.`;
955
971
  ['numberString', 29],
956
972
  ['pickles', 100],
957
973
  ],
958
- }
974
+ },
959
975
  );
960
976
  expect(testEntity.$inArray(resultEntity)).toEqual(false);
961
977
  });
@@ -972,7 +988,7 @@ This one's zip code is 92064.`;
972
988
  ['number', 30],
973
989
  ['pickles', 100],
974
990
  ],
975
- }
991
+ },
976
992
  );
977
993
  expect(testEntity.$inArray(resultEntity)).toEqual(true);
978
994
 
@@ -985,7 +1001,7 @@ This one's zip code is 92064.`;
985
1001
  ['number', 31],
986
1002
  ['pickles', 100],
987
1003
  ],
988
- }
1004
+ },
989
1005
  );
990
1006
  expect(testEntity.$inArray(resultEntity)).toEqual(true);
991
1007
 
@@ -998,7 +1014,7 @@ This one's zip code is 92064.`;
998
1014
  ['number', 29],
999
1015
  ['pickles', 100],
1000
1016
  ],
1001
- }
1017
+ },
1002
1018
  );
1003
1019
  expect(testEntity.$inArray(resultEntity)).toEqual(false);
1004
1020
 
@@ -1011,7 +1027,7 @@ This one's zip code is 92064.`;
1011
1027
  ['numberString', 30],
1012
1028
  ['pickles', 100],
1013
1029
  ],
1014
- }
1030
+ },
1015
1031
  );
1016
1032
  expect(testEntity.$inArray(resultEntity)).toEqual(true);
1017
1033
 
@@ -1024,7 +1040,7 @@ This one's zip code is 92064.`;
1024
1040
  ['numberString', 31],
1025
1041
  ['pickles', 100],
1026
1042
  ],
1027
- }
1043
+ },
1028
1044
  );
1029
1045
  expect(testEntity.$inArray(resultEntity)).toEqual(true);
1030
1046
 
@@ -1037,7 +1053,7 @@ This one's zip code is 92064.`;
1037
1053
  ['numberString', 29],
1038
1054
  ['pickles', 100],
1039
1055
  ],
1040
- }
1056
+ },
1041
1057
  );
1042
1058
  expect(testEntity.$inArray(resultEntity)).toEqual(false);
1043
1059
  });
@@ -1049,7 +1065,7 @@ This one's zip code is 92064.`;
1049
1065
  const resultEntity = await nymph.getEntities(
1050
1066
  { class: TestModel },
1051
1067
  { type: '&', tag: 'test' },
1052
- { type: '!&', gte: ['number', 60] }
1068
+ { type: '!&', gte: ['number', 60] },
1053
1069
  );
1054
1070
  expect(testEntity.$inArray(resultEntity)).toEqual(true);
1055
1071
  });
@@ -1060,7 +1076,7 @@ This one's zip code is 92064.`;
1060
1076
  // Testing wrong inequality...
1061
1077
  const resultEntity = await nymph.getEntities(
1062
1078
  { class: TestModel },
1063
- { type: '&', lte: ['number', 29.99] }
1079
+ { type: '&', lte: ['number', 29.99] },
1064
1080
  );
1065
1081
  expect(testEntity.$inArray(resultEntity)).toEqual(false);
1066
1082
  });
@@ -1071,7 +1087,7 @@ This one's zip code is 92064.`;
1071
1087
  // Retrieving entity by time...
1072
1088
  const resultEntity = await nymph.getEntities(
1073
1089
  { class: TestModel },
1074
- { type: '&', tag: 'test', gt: ['cdate', (testEntity.cdate ?? 0) - 120] }
1090
+ { type: '&', tag: 'test', gt: ['cdate', (testEntity.cdate ?? 0) - 120] },
1075
1091
  );
1076
1092
  expect(testEntity.$inArray(resultEntity)).toEqual(true);
1077
1093
  });
@@ -1082,7 +1098,7 @@ This one's zip code is 92064.`;
1082
1098
  // Testing wrong time...
1083
1099
  const resultEntity = await nymph.getEntities(
1084
1100
  { class: TestModel },
1085
- { type: '&', tag: 'test', gte: ['cdate', (testEntity.cdate ?? 0) + 1] }
1101
+ { type: '&', tag: 'test', gte: ['cdate', (testEntity.cdate ?? 0) + 1] },
1086
1102
  );
1087
1103
  expect(testEntity.$inArray(resultEntity)).toEqual(false);
1088
1104
  });
@@ -1095,7 +1111,7 @@ This one's zip code is 92064.`;
1095
1111
  // Retrieving entity by relative time...
1096
1112
  let resultEntity = await nymph.getEntities(
1097
1113
  { class: TestModel },
1098
- { type: '&', gt: ['timestamp', null, '-1 day'] }
1114
+ { type: '&', gt: ['timestamp', null, '-1 day'] },
1099
1115
  );
1100
1116
  expect(testEntity.$inArray(resultEntity)).toEqual(true);
1101
1117
  expect(referenceEntity.$inArray(resultEntity)).toEqual(false);
@@ -1109,7 +1125,7 @@ This one's zip code is 92064.`;
1109
1125
  ['timestamp', null, '-1 day'],
1110
1126
  ['timestamp', null, '+5 days'],
1111
1127
  ],
1112
- }
1128
+ },
1113
1129
  );
1114
1130
  expect(testEntity.$inArray(resultEntity)).toEqual(true);
1115
1131
  expect(referenceEntity.$inArray(resultEntity)).toEqual(false);
@@ -1117,7 +1133,7 @@ This one's zip code is 92064.`;
1117
1133
  // Retrieving entity by relative time...
1118
1134
  resultEntity = await nymph.getEntities(
1119
1135
  { class: TestModel },
1120
- { type: '&', gt: ['timestamp', null, '-3 days'] }
1136
+ { type: '&', gt: ['timestamp', null, '-3 days'] },
1121
1137
  );
1122
1138
  expect(testEntity.$inArray(resultEntity)).toEqual(true);
1123
1139
  expect(referenceEntity.$inArray(resultEntity)).toEqual(true);
@@ -1125,7 +1141,7 @@ This one's zip code is 92064.`;
1125
1141
  // Retrieving entity by relative time...
1126
1142
  resultEntity = await nymph.getEntities(
1127
1143
  { class: TestModel },
1128
- { type: '&', gt: ['cdate', null, '-1 day'] }
1144
+ { type: '&', gt: ['cdate', null, '-1 day'] },
1129
1145
  );
1130
1146
  expect(testEntity.$inArray(resultEntity)).toEqual(true);
1131
1147
  expect(referenceEntity.$inArray(resultEntity)).toEqual(true);
@@ -1139,7 +1155,7 @@ This one's zip code is 92064.`;
1139
1155
  // Retrieving entity by relative time...
1140
1156
  let resultEntity = await nymph.getEntities(
1141
1157
  { class: TestModel },
1142
- { type: '&', tag: 'test', gt: ['timestamp', null, '+1 day'] }
1158
+ { type: '&', tag: 'test', gt: ['timestamp', null, '+1 day'] },
1143
1159
  );
1144
1160
  expect(testEntity.$inArray(resultEntity)).toEqual(false);
1145
1161
  expect(referenceEntity.$inArray(resultEntity)).toEqual(false);
@@ -1147,7 +1163,7 @@ This one's zip code is 92064.`;
1147
1163
  // Retrieving entity by relative time...
1148
1164
  resultEntity = await nymph.getEntities(
1149
1165
  { class: TestModel },
1150
- { type: '&', tag: 'test', lt: ['timestamp', null, '-3 days'] }
1166
+ { type: '&', tag: 'test', lt: ['timestamp', null, '-3 days'] },
1151
1167
  );
1152
1168
  expect(testEntity.$inArray(resultEntity)).toEqual(false);
1153
1169
  expect(referenceEntity.$inArray(resultEntity)).toEqual(false);
@@ -1155,7 +1171,7 @@ This one's zip code is 92064.`;
1155
1171
  // Retrieving entity by relative time...
1156
1172
  resultEntity = await nymph.getEntities(
1157
1173
  { class: TestModel },
1158
- { type: '&', tag: 'test', gt: ['cdate', null, '+1 day'] }
1174
+ { type: '&', tag: 'test', gt: ['cdate', null, '+1 day'] },
1159
1175
  );
1160
1176
  expect(testEntity.$inArray(resultEntity)).toEqual(false);
1161
1177
  expect(referenceEntity.$inArray(resultEntity)).toEqual(false);
@@ -1165,9 +1181,11 @@ This one's zip code is 92064.`;
1165
1181
  await createTestEntities();
1166
1182
 
1167
1183
  // Testing referenced entities...
1184
+ await testEntity.reference?.$wake();
1168
1185
  expect(testEntity.reference?.test).toEqual('good');
1169
1186
 
1170
1187
  // Testing referenced entity arrays...
1188
+ await Promise.all(testEntity.refArray?.map((e) => e.$wake()) || []);
1171
1189
  expect(testEntity.refArray?.[0].test).toEqual('good');
1172
1190
  });
1173
1191
 
@@ -1177,7 +1195,7 @@ This one's zip code is 92064.`;
1177
1195
  // Retrieving entity by reference...
1178
1196
  const resultEntity = await nymph.getEntities(
1179
1197
  { class: TestModel },
1180
- { type: '&', ref: ['reference', refGuid] }
1198
+ { type: '&', ref: ['reference', refGuid] },
1181
1199
  );
1182
1200
  expect(testEntity.$inArray(resultEntity)).toEqual(true);
1183
1201
  });
@@ -1189,7 +1207,7 @@ This one's zip code is 92064.`;
1189
1207
  const resultEntity = await nymph.getEntities(
1190
1208
  { class: TestModel },
1191
1209
  { type: '&', tag: 'test' },
1192
- { type: '!&', ref: ['reference', guid()] }
1210
+ { type: '!&', ref: ['reference', guid()] },
1193
1211
  );
1194
1212
  expect(testEntity.$inArray(resultEntity)).toEqual(true);
1195
1213
  });
@@ -1200,7 +1218,7 @@ This one's zip code is 92064.`;
1200
1218
  // Testing wrong reference...
1201
1219
  const resultEntity = await nymph.getEntities(
1202
1220
  { class: TestModel },
1203
- { type: '&', ref: ['reference', guid()] }
1221
+ { type: '&', ref: ['reference', guid()] },
1204
1222
  );
1205
1223
  expect(testEntity.$inArray(resultEntity)).toEqual(false);
1206
1224
  });
@@ -1211,7 +1229,7 @@ This one's zip code is 92064.`;
1211
1229
  // Testing non-existent reference...
1212
1230
  const resultEntity = await nymph.getEntities(
1213
1231
  { class: TestModel },
1214
- { type: '&', ref: ['pickle', refGuid] }
1232
+ { type: '&', ref: ['pickle', refGuid] },
1215
1233
  );
1216
1234
  expect(testEntity.$inArray(resultEntity)).toEqual(false);
1217
1235
  });
@@ -1228,7 +1246,7 @@ This one's zip code is 92064.`;
1228
1246
  ['reference', refGuid],
1229
1247
  ['reference', guid()],
1230
1248
  ],
1231
- }
1249
+ },
1232
1250
  );
1233
1251
  expect(testEntity.$inArray(resultEntity)).toEqual(true);
1234
1252
  });
@@ -1245,7 +1263,7 @@ This one's zip code is 92064.`;
1245
1263
  ['reference', guid()],
1246
1264
  ['reference', guid()],
1247
1265
  ],
1248
- }
1266
+ },
1249
1267
  );
1250
1268
  expect(testEntity.$inArray(resultEntity)).toEqual(false);
1251
1269
  });
@@ -1256,7 +1274,7 @@ This one's zip code is 92064.`;
1256
1274
  // Retrieving entity by array reference...
1257
1275
  const resultEntity = await nymph.getEntities(
1258
1276
  { class: TestModel },
1259
- { type: '&', ref: ['refArray', refGuid] }
1277
+ { type: '&', ref: ['refArray', refGuid] },
1260
1278
  );
1261
1279
  expect(testEntity.$inArray(resultEntity)).toEqual(true);
1262
1280
  });
@@ -1273,7 +1291,7 @@ This one's zip code is 92064.`;
1273
1291
  ['refArray', refGuid],
1274
1292
  ['refArray', guid()],
1275
1293
  ],
1276
- }
1294
+ },
1277
1295
  );
1278
1296
  expect(testEntity.$inArray(resultEntity)).toEqual(false);
1279
1297
  });
@@ -1318,7 +1336,7 @@ This one's zip code is 92064.`;
1318
1336
  ['array', 'values'],
1319
1337
  ['array', 500],
1320
1338
  ],
1321
- }
1339
+ },
1322
1340
  );
1323
1341
  expect(testEntity.$inArray(resultEntity)).toEqual(true);
1324
1342
  });
@@ -1338,13 +1356,13 @@ This one's zip code is 92064.`;
1338
1356
 
1339
1357
  const resultSelectors = await nymph.getEntities(
1340
1358
  { class: TestModel },
1341
- { type: '&', ref: ['reference', refGuid] }
1359
+ { type: '&', ref: ['reference', refGuid] },
1342
1360
  );
1343
1361
 
1344
1362
  // Testing count return with selectors...
1345
1363
  const resultSelectorsCount = await nymph.getEntities(
1346
1364
  { class: TestModel, return: 'count' },
1347
- { type: '&', ref: ['reference', refGuid] }
1365
+ { type: '&', ref: ['reference', refGuid] },
1348
1366
  );
1349
1367
  expect(resultSelectorsCount).toBeGreaterThanOrEqual(1);
1350
1368
  expect(resultSelectorsCount).toEqual(resultSelectors.length);
@@ -1367,7 +1385,7 @@ This one's zip code is 92064.`;
1367
1385
  // Testing empty count...
1368
1386
  const resultSelectorsEmpty = await nymph.getEntities(
1369
1387
  { class: TestModel, return: 'count' },
1370
- { type: '&', ref: ['reference', guid()] }
1388
+ { type: '&', ref: ['reference', guid()] },
1371
1389
  );
1372
1390
  expect(resultSelectorsEmpty).toEqual(0);
1373
1391
  });
@@ -1412,7 +1430,7 @@ This one's zip code is 92064.`;
1412
1430
  ['array', 'values'],
1413
1431
  ['array', 500],
1414
1432
  ],
1415
- }
1433
+ },
1416
1434
  );
1417
1435
  expect(resultGuid.indexOf(testEntity.guid ?? '')).toBeGreaterThan(-1);
1418
1436
  });
@@ -1462,7 +1480,7 @@ This one's zip code is 92064.`;
1462
1480
  ],
1463
1481
  },
1464
1482
  ],
1465
- }
1483
+ },
1466
1484
  );
1467
1485
  expect(testEntity.$inArray(resultEntity)).toEqual(true);
1468
1486
 
@@ -1507,7 +1525,7 @@ This one's zip code is 92064.`;
1507
1525
  ],
1508
1526
  },
1509
1527
  ],
1510
- }
1528
+ },
1511
1529
  );
1512
1530
  expect(testEntity.$inArray(resultEntity2)).toEqual(true);
1513
1531
 
@@ -1523,7 +1541,7 @@ This one's zip code is 92064.`;
1523
1541
  },
1524
1542
  { type: '&', gte: ['number', 16000] },
1525
1543
  ],
1526
- }
1544
+ },
1527
1545
  );
1528
1546
  expect(testEntity.$inArray(resultEntity3)).toEqual(true);
1529
1547
 
@@ -1545,7 +1563,7 @@ This one's zip code is 92064.`;
1545
1563
  },
1546
1564
  },
1547
1565
  ],
1548
- }
1566
+ },
1549
1567
  );
1550
1568
  expect(testEntity.$inArray(resultEntity4)).toEqual(true);
1551
1569
  });
@@ -1564,7 +1582,7 @@ This one's zip code is 92064.`;
1564
1582
  },
1565
1583
  { type: '&', gte: ['number', 16000] },
1566
1584
  ],
1567
- }
1585
+ },
1568
1586
  );
1569
1587
  expect(testEntity.$inArray(resultEntity)).toEqual(false);
1570
1588
  });
@@ -1581,7 +1599,7 @@ This one's zip code is 92064.`;
1581
1599
  'reference',
1582
1600
  [{ class: TestModel }, { type: '&', equal: ['test', 'good'] }],
1583
1601
  ],
1584
- }
1602
+ },
1585
1603
  );
1586
1604
  expect(testEntity.$inArray(resultEntity)).toEqual(true);
1587
1605
  });
@@ -1598,7 +1616,7 @@ This one's zip code is 92064.`;
1598
1616
  'reference',
1599
1617
  [{ class: TestModel }, { type: '&', equal: ['test', 'pickles'] }],
1600
1618
  ],
1601
- }
1619
+ },
1602
1620
  );
1603
1621
  expect(testEntity.$inArray(resultEntity)).toEqual(true);
1604
1622
  });
@@ -1615,7 +1633,7 @@ This one's zip code is 92064.`;
1615
1633
  'reference',
1616
1634
  [{ class: TestBModel }, { type: '&', equal: ['test', 'good'] }],
1617
1635
  ],
1618
- }
1636
+ },
1619
1637
  );
1620
1638
  expect(testEntity.$inArray(resultEntity)).toEqual(false);
1621
1639
  });
@@ -1632,31 +1650,28 @@ This one's zip code is 92064.`;
1632
1650
  'reference',
1633
1651
  [{ class: TestModel }, { type: '&', equal: ['test', 'pickles'] }],
1634
1652
  ],
1635
- }
1653
+ },
1636
1654
  );
1637
1655
  expect(testEntity.$inArray(resultEntity)).toEqual(false);
1638
1656
  });
1639
1657
 
1640
- it('sort option', async () => {
1658
+ it('cdate and mdate sort option', async () => {
1641
1659
  await createMultipleTestEntities();
1642
1660
 
1643
- for (const sort of ['cdate', 'mdate']) {
1661
+ for (const sort of ['cdate', 'mdate'] as ('cdate' | 'mdate')[]) {
1644
1662
  // Retrieving entities sorted...
1645
- let resultEntities = await nymph.getEntities({
1646
- class: TestModel,
1647
- sort: sort as 'cdate' | 'mdate',
1648
- });
1663
+ let resultEntities = await nymph.getEntities({ class: TestModel, sort });
1649
1664
  expect(resultEntities.length).toBeGreaterThan(100);
1650
1665
  for (let i = 0; i < resultEntities.length - 1; i++) {
1651
- expect(
1652
- resultEntities[i + 1][sort as 'cdate' | 'mdate']
1653
- ).toBeGreaterThan(resultEntities[i][sort as 'cdate' | 'mdate'] ?? 0);
1666
+ expect(resultEntities[i + 1][sort]).toBeGreaterThan(
1667
+ resultEntities[i][sort] ?? 0,
1668
+ );
1654
1669
  }
1655
1670
 
1656
1671
  // And test the same with guid return...
1657
1672
  let resultGuids = await nymph.getEntities({
1658
1673
  class: TestModel,
1659
- sort: sort as 'cdate' | 'mdate',
1674
+ sort,
1660
1675
  return: 'guid',
1661
1676
  });
1662
1677
  expect(resultGuids.length).toBeGreaterThan(100);
@@ -1667,48 +1682,121 @@ This one's zip code is 92064.`;
1667
1682
  // Retrieving entities reverse sorted...
1668
1683
  resultEntities = await nymph.getEntities({
1669
1684
  class: TestModel,
1670
- sort: sort as 'cdate' | 'mdate',
1685
+ sort,
1671
1686
  reverse: true,
1672
1687
  });
1673
1688
  expect(resultEntities.length).toBeGreaterThan(100);
1674
1689
  for (let i = 0; i < resultEntities.length - 1; i++) {
1675
- expect(resultEntities[i + 1][sort as 'cdate' | 'mdate']).toBeLessThan(
1676
- resultEntities[i][sort as 'cdate' | 'mdate'] ?? 0
1690
+ expect(resultEntities[i + 1][sort]).toBeLessThan(
1691
+ resultEntities[i][sort] ?? 0,
1677
1692
  );
1678
1693
  }
1679
1694
 
1680
1695
  // And again with other selectors.
1681
1696
  // Retrieving entities sorted...
1682
1697
  resultEntities = await nymph.getEntities(
1683
- { class: TestModel, sort: sort as 'cdate' | 'mdate' },
1684
- { type: '&', match: ['name', '^Multi Test '] }
1698
+ { class: TestModel, sort },
1699
+ { type: '&', match: ['name', '^Multi Test '] },
1685
1700
  );
1686
1701
  expect(resultEntities.length).toEqual(100);
1687
1702
  for (let i = 0; i < resultEntities.length - 1; i++) {
1688
- expect(
1689
- resultEntities[i + 1][sort as 'cdate' | 'mdate']
1690
- ).toBeGreaterThan(resultEntities[i][sort as 'cdate' | 'mdate'] ?? 0);
1703
+ expect(resultEntities[i + 1][sort]).toBeGreaterThan(
1704
+ resultEntities[i][sort] ?? 0,
1705
+ );
1691
1706
  }
1692
1707
 
1693
1708
  // Retrieving entities reverse sorted...
1694
1709
  resultEntities = await nymph.getEntities(
1695
- { class: TestModel, sort: sort as 'cdate' | 'mdate', reverse: true },
1696
- { type: '&', match: ['name', '^Multi Test '] }
1710
+ { class: TestModel, sort, reverse: true },
1711
+ { type: '&', match: ['name', '^Multi Test '] },
1697
1712
  );
1698
1713
  expect(resultEntities.length).toEqual(100);
1699
1714
  for (let i = 0; i < resultEntities.length - 1; i++) {
1700
- expect(resultEntities[i + 1][sort as 'cdate' | 'mdate']).toBeLessThan(
1701
- resultEntities[i][sort as 'cdate' | 'mdate'] ?? 0
1715
+ expect(resultEntities[i + 1][sort]).toBeLessThan(
1716
+ resultEntities[i][sort] ?? 0,
1702
1717
  );
1703
1718
  }
1704
1719
  }
1705
1720
  });
1706
1721
 
1722
+ it('property sort option', async () => {
1723
+ await createMultipleTestEntities();
1724
+
1725
+ // Retrieving entities sorted...
1726
+ let resultEntities = await nymph.getEntities({
1727
+ class: TestModel,
1728
+ sort: 'number',
1729
+ });
1730
+ expect(resultEntities.length).toBeGreaterThan(100);
1731
+ for (let i = 0; i < resultEntities.length - 1; i++) {
1732
+ expect(resultEntities[i + 1].number ?? Infinity).toBeGreaterThanOrEqual(
1733
+ resultEntities[i].number ?? 0,
1734
+ );
1735
+ }
1736
+
1737
+ // And test the same with guid return...
1738
+ let resultGuids = await nymph.getEntities({
1739
+ class: TestModel,
1740
+ sort: 'number',
1741
+ return: 'guid',
1742
+ });
1743
+ expect(resultGuids.length).toBeGreaterThan(100);
1744
+ for (let i = 0; i < resultGuids.length - 1; i++) {
1745
+ expect(resultGuids[i]).toEqual(resultEntities[i].guid);
1746
+ }
1747
+
1748
+ // Retrieving entities reverse sorted...
1749
+ resultEntities = await nymph.getEntities({
1750
+ class: TestModel,
1751
+ sort: 'number',
1752
+ reverse: true,
1753
+ });
1754
+ expect(resultEntities.length).toBeGreaterThan(100);
1755
+ for (let i = 0; i < resultEntities.length - 1; i++) {
1756
+ expect(resultEntities[i + 1].number ?? 0).toBeLessThanOrEqual(
1757
+ resultEntities[i].number ?? Infinity,
1758
+ );
1759
+ }
1760
+
1761
+ // And again with other selectors.
1762
+ // Retrieving entities sorted...
1763
+ resultEntities = await nymph.getEntities(
1764
+ { class: TestModel, sort: 'number' },
1765
+ { type: '&', match: ['name', '^Multi Test '] },
1766
+ );
1767
+ expect(resultEntities.length).toEqual(100);
1768
+ for (let i = 0; i < resultEntities.length - 1; i++) {
1769
+ expect(resultEntities[i + 1].number ?? Infinity).toBeGreaterThan(
1770
+ resultEntities[i].number ?? 0,
1771
+ );
1772
+ expect(resultEntities[i].name).toEqual(
1773
+ `Multi Test ${100 - (resultEntities[i].number ?? 0)}`,
1774
+ );
1775
+ }
1776
+
1777
+ // Retrieving entities reverse sorted...
1778
+ resultEntities = await nymph.getEntities(
1779
+ { class: TestModel, sort: 'number', reverse: true },
1780
+ { type: '&', match: ['name', '^Multi Test '] },
1781
+ );
1782
+ expect(resultEntities.length).toEqual(100);
1783
+ for (let i = 0; i < resultEntities.length - 1; i++) {
1784
+ expect(resultEntities[i + 1].number ?? 0).toBeLessThan(
1785
+ resultEntities[i].number ?? Infinity,
1786
+ );
1787
+ expect(resultEntities[i].name).toEqual(
1788
+ `Multi Test ${100 - (resultEntities[i].number ?? 0)}`,
1789
+ );
1790
+ }
1791
+ });
1792
+
1707
1793
  it('delete reference', async () => {
1708
1794
  await createTestEntities();
1709
1795
 
1710
1796
  // Deleting referenced entities...
1797
+ await testEntity.reference?.$wake();
1711
1798
  expect(await testEntity.reference?.$delete()).toEqual(true);
1799
+ await Promise.all(testEntity.refArray?.map((e) => e.$wake()) || []);
1712
1800
  expect(testEntity.reference?.guid).toBeNull();
1713
1801
  });
1714
1802
 
@@ -1721,16 +1809,116 @@ This one's zip code is 92064.`;
1721
1809
 
1722
1810
  const entity = await nymph.getEntity(
1723
1811
  { class: TestModel },
1724
- { type: '&', guid: testGuid }
1812
+ { type: '&', guid: testGuid },
1725
1813
  );
1726
1814
 
1727
1815
  expect(entity).toBeNull();
1728
1816
  });
1817
+
1818
+ it('allows non-duplicate unique strings', async () => {
1819
+ // Creating entity...
1820
+ const uniqueEntityA = await TestModel.factory();
1821
+ uniqueEntityA.name = 'Entity Test ' + new Date().toLocaleString();
1822
+ uniqueEntityA.uniques = ['test a'];
1823
+
1824
+ // Saving entity...
1825
+ expect(await uniqueEntityA.$save()).toEqual(true);
1826
+ expect(uniqueEntityA.guid).not.toBeNull();
1827
+
1828
+ // Creating entity...
1829
+ const uniqueEntityB = await TestModel.factory();
1830
+ uniqueEntityB.name = 'Entity Test ' + new Date().toLocaleString();
1831
+ uniqueEntityB.uniques = ['test b'];
1832
+
1833
+ // Saving entity...
1834
+ expect(await uniqueEntityB.$save()).toEqual(true);
1835
+ expect(uniqueEntityB.guid).not.toBeNull();
1836
+
1837
+ expect(uniqueEntityA.guid).not.toEqual(uniqueEntityB.guid);
1838
+
1839
+ expect(await uniqueEntityA.$delete()).toEqual(true);
1840
+ expect(await uniqueEntityB.$delete()).toEqual(true);
1841
+ });
1842
+
1843
+ it('throws on duplicate unique strings', async () => {
1844
+ // Creating entity...
1845
+ const uniqueEntityA = await TestModel.factory();
1846
+ uniqueEntityA.name = 'Entity Test ' + new Date().toLocaleString();
1847
+ uniqueEntityA.uniques = ['test a'];
1848
+
1849
+ // Saving entity...
1850
+ expect(await uniqueEntityA.$save()).toEqual(true);
1851
+ expect(uniqueEntityA.guid).not.toBeNull();
1852
+
1853
+ // Creating entity...
1854
+ const uniqueEntityB = await TestModel.factory();
1855
+ uniqueEntityB.name = 'Entity Test ' + new Date().toLocaleString();
1856
+ uniqueEntityB.uniques = ['test a'];
1857
+
1858
+ // Saving entity...
1859
+ try {
1860
+ await uniqueEntityB.$save();
1861
+
1862
+ throw Error("Shouldn't get past the uniqueness check.");
1863
+ } catch (e: any) {
1864
+ expect(e).toBeInstanceOf(EntityUniqueConstraintError);
1865
+ }
1866
+ expect(uniqueEntityB.guid).toBeNull();
1867
+
1868
+ expect(await uniqueEntityA.$delete()).toEqual(true);
1869
+ });
1870
+
1871
+ it('allows duplicate unique string if first transaction is rolled back', async () => {
1872
+ // Creating transaction entity...
1873
+ const tnymphA = await nymph.startTransaction('test-unique-a');
1874
+ const TestModelA = tnymphA.getEntityClass(TestModel);
1875
+ const uniqueEntityA = await TestModelA.factory();
1876
+ uniqueEntityA.name = 'Entity Test ' + new Date().toLocaleString();
1877
+ uniqueEntityA.uniques = ['test a'];
1878
+
1879
+ // Saving entity...
1880
+ expect(await uniqueEntityA.$save()).toEqual(true);
1881
+ expect(uniqueEntityA.guid).not.toBeNull();
1882
+
1883
+ // Rolling back transaction...
1884
+ expect(await tnymphA.rollback('test-unique-a')).toEqual(true);
1885
+
1886
+ // Creating transaction entity...
1887
+ const tnymphB = await nymph.startTransaction('test-unique-b');
1888
+ const TestModelB = tnymphB.getEntityClass(TestModel);
1889
+ const uniqueEntityB = await TestModelB.factory();
1890
+ uniqueEntityB.name = 'Entity Test ' + new Date().toLocaleString();
1891
+ uniqueEntityB.uniques = ['test a'];
1892
+
1893
+ // Saving entity...
1894
+ expect(await uniqueEntityB.$save()).toEqual(true);
1895
+ expect(uniqueEntityB.guid).not.toBeNull();
1896
+
1897
+ expect(uniqueEntityA.guid).not.toEqual(uniqueEntityB.guid);
1898
+
1899
+ expect(await tnymphB.commit('test-unique-b')).toEqual(true);
1900
+
1901
+ const uniqueEntityACheck = await nymph.getEntity(
1902
+ { class: TestModel },
1903
+ { type: '&', guid: uniqueEntityA.guid ?? '' },
1904
+ );
1905
+ expect(uniqueEntityACheck).toBeNull();
1906
+
1907
+ const uniqueEntityBCheck = await nymph.getEntity(
1908
+ { class: TestModel },
1909
+ { type: '&', guid: uniqueEntityB.guid ?? '' },
1910
+ );
1911
+ expect(uniqueEntityBCheck).not.toBeNull();
1912
+
1913
+ if (uniqueEntityBCheck != null) {
1914
+ expect(await uniqueEntityBCheck.$delete()).toEqual(true);
1915
+ }
1916
+ });
1729
1917
  }
1730
1918
 
1731
1919
  export function UIDTest(
1732
1920
  nymph: Nymph,
1733
- it: (name: string, fn: () => void) => void
1921
+ it: (name: string, fn: () => void) => void,
1734
1922
  ) {
1735
1923
  it('delete old test data', async () => {
1736
1924
  expect(await nymph.deleteUID('TestUID')).toEqual(true);
@@ -1771,7 +1959,7 @@ export function UIDTest(
1771
1959
 
1772
1960
  export function ExportImportTest(
1773
1961
  nymph: Nymph,
1774
- it: (name: string, fn: () => void) => void
1962
+ it: (name: string, fn: () => void) => void,
1775
1963
  ) {
1776
1964
  const TestModel = nymph.addEntityClass(TestModelClass);
1777
1965
  const TestBModel = nymph.addEntityClass(TestBModelClass);
@@ -1807,23 +1995,39 @@ export function ExportImportTest(
1807
1995
  const bmodels = await nymph.getEntities({ class: TestBModel });
1808
1996
 
1809
1997
  expect(models.length).toEqual(30);
1810
- expect(bmodels.length).toEqual(10);
1811
-
1812
- const all = [...models, ...bmodels];
1813
- for (const model of all) {
1814
- if (model.index?.match(/^\d+a$/)) {
1815
- expect(model.null).toBeNull();
1816
- expect(model.string).toEqual('test');
1817
- expect(model.array).toEqual(['full', 'of', 'values', 500]);
1818
- expect(model.number).toEqual(30);
1819
- expect(model.timestamp).toBeGreaterThanOrEqual(strtotime('-2 minutes'));
1820
-
1821
- expect(model.reference?.guid).not.toBeNull();
1822
- expect(model.reference?.string).toEqual('another');
1823
- expect(model.reference?.index?.match(/^\d+b$/)).toBeTruthy();
1824
- expect(model.refArray?.[0].guid).not.toBeNull();
1825
- expect(model.refArray?.[0].guid).toEqual(model.reference?.guid);
1826
- }
1998
+ expect(bmodels.length).toEqual(30);
1999
+
2000
+ for (const model of models) {
2001
+ expect(model.name).toMatch(/^Entity Test /);
2002
+ expect(model.null).toBeDefined();
2003
+ expect(model.null).toBeNull();
2004
+ expect(model.string).toEqual('test');
2005
+ expect(model.array).toEqual(['full', 'of', 'values', 500]);
2006
+ expect(model.match)
2007
+ .toEqual(`Hello, my name is Edward McCheese. It is a pleasure to meet you. As you can see, I have several hats of the most pleasant nature.
2008
+
2009
+ This one's email address is nice_hat-wednesday+newyork@im-a-hat.hat.
2010
+ This one's phone number is (555) 555-1818.
2011
+ This one's zip code is 92064.
2012
+ This one's favorite emojis are 🔥❤️😊😂⭐🤔
2013
+
2014
+ These hats are absolutely fantastic.`);
2015
+ expect(model.number).toEqual(30);
2016
+ expect(model.numberString).toEqual('30');
2017
+ expect(model.timestamp).toBeGreaterThanOrEqual(strtotime('-2 minutes'));
2018
+ expect(model.index).toMatch(/^\d+a$/);
2019
+
2020
+ await model.reference?.$wake();
2021
+ expect(model.reference?.guid).not.toBeNull();
2022
+ expect(model.reference?.string).toEqual('another');
2023
+ expect(model.reference?.index).toMatch(/^\d+b$/);
2024
+ expect(model.index?.substring(0, -1)).toEqual(
2025
+ model.reference?.index?.substring(0, -1),
2026
+ );
2027
+ expect(model.reference?.$inArray(bmodels)).toEqual(true);
2028
+ await Promise.all(model.refArray?.map((e) => e.$wake()) || []);
2029
+ expect(model.refArray?.[0].guid).not.toBeNull();
2030
+ expect(model.refArray?.[0].guid).toEqual(model.reference?.guid);
1827
2031
  }
1828
2032
  }
1829
2033
 
@@ -1836,22 +2040,29 @@ export function ExportImportTest(
1836
2040
  expect(await nymph.newUID('TestUID')).toEqual(2);
1837
2041
  expect(await nymph.newUID('TestUID2')).toEqual(1);
1838
2042
 
1839
- for (let i = 0; i < 20; i++) {
1840
- const EntityClass = i < 15 ? TestModel : TestBModel;
1841
-
2043
+ for (let i = 0; i < 30; i++) {
1842
2044
  // Creating entity...
1843
- const testEntity = await EntityClass.factory();
2045
+ const testEntity = await TestModel.factory();
1844
2046
 
1845
2047
  // Saving entity...
1846
2048
  testEntity.name = 'Entity Test ' + new Date().toLocaleString();
1847
2049
  testEntity.null = null;
1848
2050
  testEntity.string = 'test';
1849
2051
  testEntity.array = ['full', 'of', 'values', 500];
2052
+ testEntity.match = `Hello, my name is Edward McCheese. It is a pleasure to meet you. As you can see, I have several hats of the most pleasant nature.
2053
+
2054
+ This one's email address is nice_hat-wednesday+newyork@im-a-hat.hat.
2055
+ This one's phone number is (555) 555-1818.
2056
+ This one's zip code is 92064.
2057
+ This one's favorite emojis are 🔥❤️😊😂⭐🤔
2058
+
2059
+ These hats are absolutely fantastic.`;
1850
2060
  testEntity.number = 30;
2061
+ testEntity.numberString = '30';
1851
2062
  testEntity.timestamp = Date.now();
1852
2063
  testEntity.index = i + 'a';
1853
2064
 
1854
- const entityReferenceTest = await EntityClass.factory();
2065
+ const entityReferenceTest = await TestBModel.factory();
1855
2066
  entityReferenceTest.string = 'another';
1856
2067
  entityReferenceTest.index = i + 'b';
1857
2068
 
@@ -1867,7 +2078,7 @@ export function ExportImportTest(
1867
2078
 
1868
2079
  it('export data', async () => {
1869
2080
  expect(await nymph.export(__dirname + '/testentityexport.nex')).toEqual(
1870
- true
2081
+ true,
1871
2082
  );
1872
2083
  });
1873
2084
 
@@ -1884,7 +2095,7 @@ export function ExportImportTest(
1884
2095
  expect(bmodels.length).toEqual(0);
1885
2096
 
1886
2097
  expect(await nymph.import(__dirname + '/testentityexport.nex')).toEqual(
1887
- true
2098
+ true,
1888
2099
  );
1889
2100
 
1890
2101
  await checkEntityDataAndCount();