@nymphjs/nymph 1.0.0-beta.4 → 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/CHANGELOG.md +195 -0
- package/README.md +12 -12
- package/dist/Entity.d.ts +24 -3
- package/dist/Entity.js +194 -86
- package/dist/Entity.js.map +1 -1
- package/dist/Entity.test.js +34 -17
- package/dist/Entity.test.js.map +1 -1
- package/dist/Entity.types.d.ts +3 -1
- package/dist/Nymph.d.ts +22 -7
- package/dist/Nymph.js +214 -68
- package/dist/Nymph.js.map +1 -1
- package/dist/Nymph.types.d.ts +18 -5
- package/dist/Nymph.types.js +1 -1
- package/dist/Nymph.types.js.map +1 -1
- package/dist/driver/NymphDriver.d.ts +1 -22
- package/dist/driver/NymphDriver.js +2 -16
- package/dist/driver/NymphDriver.js.map +1 -1
- package/dist/driver/testArtifacts.js +208 -159
- package/dist/driver/testArtifacts.js.map +1 -1
- package/dist/errors/InvalidStateError.d.ts +3 -0
- package/dist/errors/InvalidStateError.js +11 -0
- package/dist/errors/InvalidStateError.js.map +1 -0
- package/dist/errors/index.d.ts +1 -0
- package/dist/errors/index.js +1 -0
- package/dist/errors/index.js.map +1 -1
- package/dist/testArtifacts.d.ts +10 -3
- package/dist/testArtifacts.js +20 -11
- package/dist/testArtifacts.js.map +1 -1
- package/dist/testMocks.d.ts +10 -7
- package/dist/testMocks.js +22 -10
- package/dist/testMocks.js.map +1 -1
- package/dist/utils.d.ts +1 -1
- package/dist/utils.js +11 -5
- package/dist/utils.js.map +1 -1
- package/package.json +13 -13
- package/src/Entity.test.ts +31 -9
- package/src/Entity.ts +289 -113
- package/src/Entity.types.ts +13 -1
- package/src/Nymph.ts +386 -82
- package/src/Nymph.types.ts +76 -5
- package/src/driver/NymphDriver.ts +19 -85
- package/src/driver/testArtifacts.ts +125 -44
- package/src/errors/InvalidStateError.ts +6 -0
- package/src/errors/index.ts +2 -0
- package/src/testArtifacts.ts +28 -10
- package/src/testMocks.ts +38 -21
- package/src/utils.ts +21 -7
- package/typedoc.json +4 -0
package/src/Nymph.types.ts
CHANGED
|
@@ -9,18 +9,31 @@ export type NymphEventType =
|
|
|
9
9
|
| 'beforeGetEntities'
|
|
10
10
|
| 'beforeSaveEntity'
|
|
11
11
|
| 'afterSaveEntity'
|
|
12
|
+
| 'failedSaveEntity'
|
|
12
13
|
| 'beforeDeleteEntity'
|
|
13
14
|
| 'afterDeleteEntity'
|
|
15
|
+
| 'failedDeleteEntity'
|
|
14
16
|
| 'beforeDeleteEntityByID'
|
|
15
17
|
| 'afterDeleteEntityByID'
|
|
18
|
+
| 'failedDeleteEntityByID'
|
|
16
19
|
| 'beforeNewUID'
|
|
17
20
|
| 'afterNewUID'
|
|
21
|
+
| 'failedNewUID'
|
|
18
22
|
| 'beforeSetUID'
|
|
19
23
|
| 'afterSetUID'
|
|
24
|
+
| 'failedSetUID'
|
|
20
25
|
| 'beforeRenameUID'
|
|
21
26
|
| 'afterRenameUID'
|
|
27
|
+
| 'failedRenameUID'
|
|
22
28
|
| 'beforeDeleteUID'
|
|
23
|
-
| 'afterDeleteUID'
|
|
29
|
+
| 'afterDeleteUID'
|
|
30
|
+
| 'failedDeleteUID'
|
|
31
|
+
| 'beforeStartTransaction'
|
|
32
|
+
| 'afterStartTransaction'
|
|
33
|
+
| 'beforeCommitTransaction'
|
|
34
|
+
| 'afterCommitTransaction'
|
|
35
|
+
| 'beforeRollbackTransaction'
|
|
36
|
+
| 'afterRollbackTransaction';
|
|
24
37
|
export type NymphConnectCallback = (
|
|
25
38
|
nymph: Nymph,
|
|
26
39
|
result: Promise<boolean>
|
|
@@ -63,6 +76,10 @@ export type NymphAfterSaveEntityCallback = (
|
|
|
63
76
|
nymph: Nymph,
|
|
64
77
|
result: Promise<boolean>
|
|
65
78
|
) => Promise<void>;
|
|
79
|
+
export type NymphFailedSaveEntityCallback = (
|
|
80
|
+
nymph: Nymph,
|
|
81
|
+
error: any
|
|
82
|
+
) => Promise<void>;
|
|
66
83
|
export type NymphBeforeDeleteEntityCallback = (
|
|
67
84
|
nymph: Nymph,
|
|
68
85
|
entity: EntityInterface
|
|
@@ -71,6 +88,10 @@ export type NymphAfterDeleteEntityCallback = (
|
|
|
71
88
|
nymph: Nymph,
|
|
72
89
|
result: Promise<boolean>
|
|
73
90
|
) => Promise<void>;
|
|
91
|
+
export type NymphFailedDeleteEntityCallback = (
|
|
92
|
+
nymph: Nymph,
|
|
93
|
+
error: any
|
|
94
|
+
) => Promise<void>;
|
|
74
95
|
export type NymphBeforeDeleteEntityByIDCallback = (
|
|
75
96
|
nymph: Nymph,
|
|
76
97
|
guid: string,
|
|
@@ -80,6 +101,10 @@ export type NymphAfterDeleteEntityByIDCallback = (
|
|
|
80
101
|
nymph: Nymph,
|
|
81
102
|
result: Promise<boolean>
|
|
82
103
|
) => Promise<void>;
|
|
104
|
+
export type NymphFailedDeleteEntityByIDCallback = (
|
|
105
|
+
nymph: Nymph,
|
|
106
|
+
error: any
|
|
107
|
+
) => Promise<void>;
|
|
83
108
|
export type NymphBeforeNewUIDCallback = (
|
|
84
109
|
nymph: Nymph,
|
|
85
110
|
name: string
|
|
@@ -88,6 +113,10 @@ export type NymphAfterNewUIDCallback = (
|
|
|
88
113
|
nymph: Nymph,
|
|
89
114
|
result: Promise<number | null>
|
|
90
115
|
) => Promise<void>;
|
|
116
|
+
export type NymphFailedNewUIDCallback = (
|
|
117
|
+
nymph: Nymph,
|
|
118
|
+
error: any
|
|
119
|
+
) => Promise<void>;
|
|
91
120
|
export type NymphBeforeSetUIDCallback = (
|
|
92
121
|
nymph: Nymph,
|
|
93
122
|
name: string,
|
|
@@ -97,6 +126,10 @@ export type NymphAfterSetUIDCallback = (
|
|
|
97
126
|
nymph: Nymph,
|
|
98
127
|
result: Promise<boolean>
|
|
99
128
|
) => Promise<void>;
|
|
129
|
+
export type NymphFailedSetUIDCallback = (
|
|
130
|
+
nymph: Nymph,
|
|
131
|
+
error: any
|
|
132
|
+
) => Promise<void>;
|
|
100
133
|
export type NymphBeforeRenameUIDCallback = (
|
|
101
134
|
nymph: Nymph,
|
|
102
135
|
oldName: string,
|
|
@@ -106,6 +139,10 @@ export type NymphAfterRenameUIDCallback = (
|
|
|
106
139
|
nymph: Nymph,
|
|
107
140
|
result: Promise<boolean>
|
|
108
141
|
) => Promise<void>;
|
|
142
|
+
export type NymphFailedRenameUIDCallback = (
|
|
143
|
+
nymph: Nymph,
|
|
144
|
+
error: any
|
|
145
|
+
) => Promise<void>;
|
|
109
146
|
export type NymphBeforeDeleteUIDCallback = (
|
|
110
147
|
nymph: Nymph,
|
|
111
148
|
name: string
|
|
@@ -114,13 +151,44 @@ export type NymphAfterDeleteUIDCallback = (
|
|
|
114
151
|
nymph: Nymph,
|
|
115
152
|
result: Promise<boolean>
|
|
116
153
|
) => Promise<void>;
|
|
154
|
+
export type NymphFailedDeleteUIDCallback = (
|
|
155
|
+
nymph: Nymph,
|
|
156
|
+
error: any
|
|
157
|
+
) => Promise<void>;
|
|
158
|
+
export type NymphBeforeStartTransactionCallback = (
|
|
159
|
+
nymph: Nymph,
|
|
160
|
+
name: string
|
|
161
|
+
) => Promise<void>;
|
|
162
|
+
export type NymphAfterStartTransactionCallback = (
|
|
163
|
+
nymph: Nymph,
|
|
164
|
+
name: string,
|
|
165
|
+
result: Nymph
|
|
166
|
+
) => Promise<void>;
|
|
167
|
+
export type NymphBeforeCommitTransactionCallback = (
|
|
168
|
+
nymph: Nymph,
|
|
169
|
+
name: string
|
|
170
|
+
) => Promise<void>;
|
|
171
|
+
export type NymphAfterCommitTransactionCallback = (
|
|
172
|
+
nymph: Nymph,
|
|
173
|
+
name: string,
|
|
174
|
+
result: boolean
|
|
175
|
+
) => Promise<void>;
|
|
176
|
+
export type NymphBeforeRollbackTransactionCallback = (
|
|
177
|
+
nymph: Nymph,
|
|
178
|
+
name: string
|
|
179
|
+
) => Promise<void>;
|
|
180
|
+
export type NymphAfterRollbackTransactionCallback = (
|
|
181
|
+
nymph: Nymph,
|
|
182
|
+
name: string,
|
|
183
|
+
result: boolean
|
|
184
|
+
) => Promise<void>;
|
|
117
185
|
|
|
118
186
|
export type Options<T extends EntityConstructor = EntityConstructor> = {
|
|
119
187
|
class?: T;
|
|
120
188
|
limit?: number;
|
|
121
189
|
offset?: number;
|
|
122
190
|
reverse?: boolean;
|
|
123
|
-
sort?: 'cdate' | 'mdate';
|
|
191
|
+
sort?: 'cdate' | 'mdate' | string;
|
|
124
192
|
return?: 'entity' | 'guid' | 'count';
|
|
125
193
|
source?: string;
|
|
126
194
|
skipCache?: boolean;
|
|
@@ -308,10 +376,13 @@ export interface TilmeldInterface {
|
|
|
308
376
|
response: any;
|
|
309
377
|
init(nymph: Nymph): void;
|
|
310
378
|
clone(): TilmeldInterface;
|
|
311
|
-
gatekeeper(ability?: string): boolean
|
|
312
|
-
authenticate():
|
|
379
|
+
gatekeeper(ability?: string): Promise<boolean>;
|
|
380
|
+
authenticate(): Promise<boolean>;
|
|
313
381
|
clearSession(): void;
|
|
314
382
|
extractToken(token: string): Promise<any>;
|
|
315
383
|
fillSession(user: any): void;
|
|
316
|
-
checkClientUIDPermissions(
|
|
384
|
+
checkClientUIDPermissions(
|
|
385
|
+
name: string,
|
|
386
|
+
type?: TilmeldAccessLevels
|
|
387
|
+
): Promise<boolean>;
|
|
317
388
|
}
|
|
@@ -54,7 +54,18 @@ export default abstract class NymphDriver {
|
|
|
54
54
|
*/
|
|
55
55
|
private putDataCounter = 0;
|
|
56
56
|
|
|
57
|
+
/**
|
|
58
|
+
* This is used internally by Nymph. Don't call it yourself.
|
|
59
|
+
*
|
|
60
|
+
* @returns A clone of this instance.
|
|
61
|
+
*/
|
|
62
|
+
abstract clone(): NymphDriver;
|
|
63
|
+
|
|
64
|
+
/**
|
|
65
|
+
* Connect to the data store.
|
|
66
|
+
*/
|
|
57
67
|
abstract connect(): Promise<boolean>;
|
|
68
|
+
|
|
58
69
|
abstract isConnected(): boolean;
|
|
59
70
|
abstract startTransaction(name: string): Promise<Nymph>;
|
|
60
71
|
abstract commit(name: string): Promise<boolean>;
|
|
@@ -66,7 +77,12 @@ export default abstract class NymphDriver {
|
|
|
66
77
|
): Promise<boolean>;
|
|
67
78
|
abstract deleteEntityByID(guid: string, className?: string): Promise<boolean>;
|
|
68
79
|
abstract deleteUID(name: string): Promise<boolean>;
|
|
80
|
+
|
|
81
|
+
/**
|
|
82
|
+
* Disconnect from the data store.
|
|
83
|
+
*/
|
|
69
84
|
abstract disconnect(): Promise<boolean>;
|
|
85
|
+
|
|
70
86
|
protected abstract exportEntities(
|
|
71
87
|
writeLine: (line: string) => void
|
|
72
88
|
): Promise<void>;
|
|
@@ -86,30 +102,6 @@ export default abstract class NymphDriver {
|
|
|
86
102
|
options?: Options<T>,
|
|
87
103
|
...selectors: Selector[]
|
|
88
104
|
): Promise<ReturnType<T['factorySync']>[] | string[] | number>;
|
|
89
|
-
protected abstract getEntitiesSync<
|
|
90
|
-
T extends EntityConstructor = EntityConstructor
|
|
91
|
-
>(
|
|
92
|
-
options: Options<T> & { return: 'count' },
|
|
93
|
-
...selectors: Selector[]
|
|
94
|
-
): number;
|
|
95
|
-
protected abstract getEntitiesSync<
|
|
96
|
-
T extends EntityConstructor = EntityConstructor
|
|
97
|
-
>(
|
|
98
|
-
options: Options<T> & { return: 'guid' },
|
|
99
|
-
...selectors: Selector[]
|
|
100
|
-
): string[];
|
|
101
|
-
protected abstract getEntitiesSync<
|
|
102
|
-
T extends EntityConstructor = EntityConstructor
|
|
103
|
-
>(
|
|
104
|
-
options?: Options<T>,
|
|
105
|
-
...selectors: Selector[]
|
|
106
|
-
): ReturnType<T['factorySync']>[];
|
|
107
|
-
protected abstract getEntitiesSync<
|
|
108
|
-
T extends EntityConstructor = EntityConstructor
|
|
109
|
-
>(
|
|
110
|
-
options?: Options<T>,
|
|
111
|
-
...selectors: Selector[]
|
|
112
|
-
): ReturnType<T['factorySync']>[] | string[] | number;
|
|
113
105
|
abstract getUID(name: string): Promise<number | null>;
|
|
114
106
|
abstract import(filename: string): Promise<boolean>;
|
|
115
107
|
abstract newUID(name: string): Promise<number | null>;
|
|
@@ -609,10 +601,9 @@ export default abstract class NymphDriver {
|
|
|
609
601
|
for (let i = 0; i < tmpArr.length; i++) {
|
|
610
602
|
const name = tmpArr[i][0];
|
|
611
603
|
const [qrefOptions, ...qrefSelectors] = tmpArr[i][1];
|
|
612
|
-
const QrefEntityClass =
|
|
613
|
-
|
|
614
|
-
|
|
615
|
-
: qrefOptions.class ?? this.nymph.getEntityClass('Entity');
|
|
604
|
+
const QrefEntityClass = qrefOptions.class
|
|
605
|
+
? this.nymph.getEntityClass(qrefOptions.class)
|
|
606
|
+
: this.nymph.getEntityClass('Entity');
|
|
616
607
|
const newOptions = {
|
|
617
608
|
...qrefOptions,
|
|
618
609
|
class: QrefEntityClass,
|
|
@@ -703,63 +694,6 @@ export default abstract class NymphDriver {
|
|
|
703
694
|
return queryParts;
|
|
704
695
|
}
|
|
705
696
|
|
|
706
|
-
/**
|
|
707
|
-
* Get the first entity to match all options/selectors, synchronously.
|
|
708
|
-
*
|
|
709
|
-
* This should really only be used internally by the Entity class. It's a bad
|
|
710
|
-
* idea to get entities synchronously. The Entity class uses this to load
|
|
711
|
-
* sleeping references.
|
|
712
|
-
*
|
|
713
|
-
* @param options The options.
|
|
714
|
-
* @param selectors Unlimited optional selectors to search for, or a single GUID. If none are given, all entities are searched for the given options.
|
|
715
|
-
* @returns An entity, or null on failure or nothing found.
|
|
716
|
-
*/
|
|
717
|
-
public getEntitySync<T extends EntityConstructor = EntityConstructor>(
|
|
718
|
-
options: Options<T> & { return: 'count' },
|
|
719
|
-
...selectors: Selector[]
|
|
720
|
-
): number;
|
|
721
|
-
public getEntitySync<T extends EntityConstructor = EntityConstructor>(
|
|
722
|
-
options: Options<T> & { return: 'guid' },
|
|
723
|
-
...selectors: Selector[]
|
|
724
|
-
): string | null;
|
|
725
|
-
public getEntitySync<T extends EntityConstructor = EntityConstructor>(
|
|
726
|
-
options: Options<T>,
|
|
727
|
-
...selectors: Selector[]
|
|
728
|
-
): ReturnType<T['factorySync']> | null;
|
|
729
|
-
public getEntitySync<T extends EntityConstructor = EntityConstructor>(
|
|
730
|
-
options: Options<T> & { return: 'count' },
|
|
731
|
-
guid: string
|
|
732
|
-
): number;
|
|
733
|
-
public getEntitySync<T extends EntityConstructor = EntityConstructor>(
|
|
734
|
-
options: Options<T> & { return: 'guid' },
|
|
735
|
-
guid: string
|
|
736
|
-
): string | null;
|
|
737
|
-
public getEntitySync<T extends EntityConstructor = EntityConstructor>(
|
|
738
|
-
options: Options<T>,
|
|
739
|
-
guid: string
|
|
740
|
-
): ReturnType<T['factorySync']> | null;
|
|
741
|
-
public getEntitySync<T extends EntityConstructor = EntityConstructor>(
|
|
742
|
-
options: Options<T> = {},
|
|
743
|
-
...selectors: Selector[] | string[]
|
|
744
|
-
): ReturnType<T['factorySync']> | string | number | null {
|
|
745
|
-
// Set up options and selectors.
|
|
746
|
-
if (typeof selectors[0] === 'string') {
|
|
747
|
-
selectors = [{ type: '&', guid: selectors[0] }];
|
|
748
|
-
}
|
|
749
|
-
options.limit = 1;
|
|
750
|
-
const entities = this.getEntitiesSync(
|
|
751
|
-
options,
|
|
752
|
-
...(selectors as Selector[])
|
|
753
|
-
);
|
|
754
|
-
if (options.return === 'count') {
|
|
755
|
-
return entities as unknown as number;
|
|
756
|
-
}
|
|
757
|
-
if (!entities || !entities.length) {
|
|
758
|
-
return null;
|
|
759
|
-
}
|
|
760
|
-
return entities[0];
|
|
761
|
-
}
|
|
762
|
-
|
|
763
697
|
protected getEntitesRowLike<T extends EntityConstructor = EntityConstructor>(
|
|
764
698
|
options: Options<T> & { return: 'count' },
|
|
765
699
|
selectors: Selector[],
|
|
@@ -3,16 +3,22 @@ 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 {
|
|
6
|
+
import {
|
|
7
|
+
TestBModel as TestBModelClass,
|
|
8
|
+
TestModel as TestModelClass,
|
|
9
|
+
TestModelData,
|
|
10
|
+
TestEmptyModel as TestEmptyModelClass,
|
|
11
|
+
} from '../testArtifacts';
|
|
7
12
|
|
|
8
13
|
export function QueriesTest(
|
|
9
14
|
nymph: Nymph,
|
|
10
15
|
it: (name: string, fn: () => void) => void
|
|
11
16
|
) {
|
|
12
|
-
nymph.addEntityClass(
|
|
13
|
-
nymph.addEntityClass(
|
|
17
|
+
const TestModel = nymph.addEntityClass(TestModelClass);
|
|
18
|
+
const TestBModel = nymph.addEntityClass(TestBModelClass);
|
|
19
|
+
const TestEmptyModel = nymph.addEntityClass(TestEmptyModelClass);
|
|
14
20
|
|
|
15
|
-
let testEntity:
|
|
21
|
+
let testEntity: TestModelClass & TestModelData;
|
|
16
22
|
let testGuid: string;
|
|
17
23
|
let refGuid: string;
|
|
18
24
|
let createdMultiple = false;
|
|
@@ -35,7 +41,10 @@ export function QueriesTest(
|
|
|
35
41
|
|
|
36
42
|
This one's email address is nice_hat-wednesday+newyork@im-a-hat.hat.
|
|
37
43
|
This one's phone number is (555) 555-1818.
|
|
38
|
-
This one's zip code is 92064
|
|
44
|
+
This one's zip code is 92064.
|
|
45
|
+
This one's favorite emojis are 🔥❤️😊😂⭐🤔
|
|
46
|
+
|
|
47
|
+
These hats are absolutely fantastic.`;
|
|
39
48
|
testEntity.number = 30;
|
|
40
49
|
testEntity.numberString = '30';
|
|
41
50
|
testEntity.timestamp = Date.now();
|
|
@@ -43,7 +52,7 @@ This one's zip code is 92064.`;
|
|
|
43
52
|
expect(testEntity.guid).not.toBeNull();
|
|
44
53
|
testGuid = testEntity.guid as string;
|
|
45
54
|
|
|
46
|
-
const entityReferenceTest:
|
|
55
|
+
const entityReferenceTest: TestModelClass & TestModelData = new TestModel();
|
|
47
56
|
entityReferenceTest.string = 'wrong';
|
|
48
57
|
entityReferenceTest.timestamp = strtotime('-2 days') * 1000;
|
|
49
58
|
expect(await entityReferenceTest.$save()).toEqual(true);
|
|
@@ -55,19 +64,11 @@ This one's zip code is 92064.`;
|
|
|
55
64
|
entityReferenceTest.test = 'good';
|
|
56
65
|
expect(await entityReferenceTest.$save()).toEqual(true);
|
|
57
66
|
|
|
58
|
-
// Test synchronous getEntity.
|
|
59
|
-
testEntity = nymph.driver.getEntitySync(
|
|
60
|
-
{ class: TestModel },
|
|
61
|
-
testGuid
|
|
62
|
-
) as TestModel & TestModelData;
|
|
63
|
-
expect(testEntity).toBeInstanceOf(TestModel);
|
|
64
|
-
expect(testEntity.guid).toEqual(testGuid);
|
|
65
|
-
|
|
66
67
|
// Test asynchronous getEntity.
|
|
67
68
|
testEntity = (await nymph.getEntity(
|
|
68
69
|
{ class: TestModel },
|
|
69
70
|
testGuid
|
|
70
|
-
)) as
|
|
71
|
+
)) as TestModelClass & TestModelData;
|
|
71
72
|
expect(testEntity).toBeInstanceOf(TestModel);
|
|
72
73
|
expect(testEntity.guid).toEqual(testGuid);
|
|
73
74
|
}
|
|
@@ -80,6 +81,8 @@ This one's zip code is 92064.`;
|
|
|
80
81
|
for (let i = 0; i < 100; i++) {
|
|
81
82
|
const testEntity = await TestModel.factory();
|
|
82
83
|
testEntity.name = `Multi Test ${i}`;
|
|
84
|
+
// Reverse the number for sort testing.
|
|
85
|
+
testEntity.number = 100 - i;
|
|
83
86
|
testEntity.$removeTag('test');
|
|
84
87
|
testEntity.$addTag('multiTest');
|
|
85
88
|
expect(await testEntity.$save()).toEqual(true);
|
|
@@ -104,6 +107,13 @@ This one's zip code is 92064.`;
|
|
|
104
107
|
await createTestEntities();
|
|
105
108
|
});
|
|
106
109
|
|
|
110
|
+
it("doesn't create empty entity", async () => {
|
|
111
|
+
const testEntity = await TestEmptyModel.factory();
|
|
112
|
+
|
|
113
|
+
expect(await testEntity.$save()).toBeFalsy();
|
|
114
|
+
expect(testEntity.guid).toBeNull();
|
|
115
|
+
});
|
|
116
|
+
|
|
107
117
|
it('update mdate on save', async () => {
|
|
108
118
|
await createTestEntities();
|
|
109
119
|
|
|
@@ -191,12 +201,12 @@ This one's zip code is 92064.`;
|
|
|
191
201
|
testEntity = (await transaction.getEntity(
|
|
192
202
|
{ class: TestModel },
|
|
193
203
|
testGuid
|
|
194
|
-
)) as
|
|
204
|
+
)) as TestModelClass & TestModelData;
|
|
195
205
|
|
|
196
206
|
expect(testEntity.guid).toEqual(testGuid);
|
|
197
207
|
|
|
198
|
-
// Start a new transaction.
|
|
199
|
-
transaction = await nymph.startTransaction('test');
|
|
208
|
+
// Start a new transaction with a dot in the name.
|
|
209
|
+
transaction = await nymph.startTransaction('test.1');
|
|
200
210
|
testEntity.$nymph = transaction;
|
|
201
211
|
|
|
202
212
|
// Verify in a transaction.
|
|
@@ -207,7 +217,7 @@ This one's zip code is 92064.`;
|
|
|
207
217
|
expect(await testEntity.$save()).toEqual(true);
|
|
208
218
|
|
|
209
219
|
// Commit the transaction.
|
|
210
|
-
await transaction.commit('test');
|
|
220
|
+
await transaction.commit('test.1');
|
|
211
221
|
testEntity.$nymph = nymph;
|
|
212
222
|
|
|
213
223
|
// Verify not in a transaction.
|
|
@@ -1161,9 +1171,11 @@ This one's zip code is 92064.`;
|
|
|
1161
1171
|
await createTestEntities();
|
|
1162
1172
|
|
|
1163
1173
|
// Testing referenced entities...
|
|
1174
|
+
await testEntity.reference?.$wake();
|
|
1164
1175
|
expect(testEntity.reference?.test).toEqual('good');
|
|
1165
1176
|
|
|
1166
1177
|
// Testing referenced entity arrays...
|
|
1178
|
+
await Promise.all(testEntity.refArray?.map((e) => e.$wake()) || []);
|
|
1167
1179
|
expect(testEntity.refArray?.[0].test).toEqual('good');
|
|
1168
1180
|
});
|
|
1169
1181
|
|
|
@@ -1633,26 +1645,23 @@ This one's zip code is 92064.`;
|
|
|
1633
1645
|
expect(testEntity.$inArray(resultEntity)).toEqual(false);
|
|
1634
1646
|
});
|
|
1635
1647
|
|
|
1636
|
-
it('sort option', async () => {
|
|
1648
|
+
it('cdate and mdate sort option', async () => {
|
|
1637
1649
|
await createMultipleTestEntities();
|
|
1638
1650
|
|
|
1639
|
-
for (const sort of ['cdate', 'mdate']) {
|
|
1651
|
+
for (const sort of ['cdate', 'mdate'] as ('cdate' | 'mdate')[]) {
|
|
1640
1652
|
// Retrieving entities sorted...
|
|
1641
|
-
let resultEntities = await nymph.getEntities({
|
|
1642
|
-
class: TestModel,
|
|
1643
|
-
sort: sort as 'cdate' | 'mdate',
|
|
1644
|
-
});
|
|
1653
|
+
let resultEntities = await nymph.getEntities({ class: TestModel, sort });
|
|
1645
1654
|
expect(resultEntities.length).toBeGreaterThan(100);
|
|
1646
1655
|
for (let i = 0; i < resultEntities.length - 1; i++) {
|
|
1647
|
-
expect(
|
|
1648
|
-
resultEntities[i
|
|
1649
|
-
)
|
|
1656
|
+
expect(resultEntities[i + 1][sort]).toBeGreaterThan(
|
|
1657
|
+
resultEntities[i][sort] ?? 0
|
|
1658
|
+
);
|
|
1650
1659
|
}
|
|
1651
1660
|
|
|
1652
1661
|
// And test the same with guid return...
|
|
1653
1662
|
let resultGuids = await nymph.getEntities({
|
|
1654
1663
|
class: TestModel,
|
|
1655
|
-
sort
|
|
1664
|
+
sort,
|
|
1656
1665
|
return: 'guid',
|
|
1657
1666
|
});
|
|
1658
1667
|
expect(resultGuids.length).toBeGreaterThan(100);
|
|
@@ -1663,48 +1672,121 @@ This one's zip code is 92064.`;
|
|
|
1663
1672
|
// Retrieving entities reverse sorted...
|
|
1664
1673
|
resultEntities = await nymph.getEntities({
|
|
1665
1674
|
class: TestModel,
|
|
1666
|
-
sort
|
|
1675
|
+
sort,
|
|
1667
1676
|
reverse: true,
|
|
1668
1677
|
});
|
|
1669
1678
|
expect(resultEntities.length).toBeGreaterThan(100);
|
|
1670
1679
|
for (let i = 0; i < resultEntities.length - 1; i++) {
|
|
1671
|
-
expect(resultEntities[i + 1][sort
|
|
1672
|
-
resultEntities[i][sort
|
|
1680
|
+
expect(resultEntities[i + 1][sort]).toBeLessThan(
|
|
1681
|
+
resultEntities[i][sort] ?? 0
|
|
1673
1682
|
);
|
|
1674
1683
|
}
|
|
1675
1684
|
|
|
1676
1685
|
// And again with other selectors.
|
|
1677
1686
|
// Retrieving entities sorted...
|
|
1678
1687
|
resultEntities = await nymph.getEntities(
|
|
1679
|
-
{ class: TestModel, sort
|
|
1688
|
+
{ class: TestModel, sort },
|
|
1680
1689
|
{ type: '&', match: ['name', '^Multi Test '] }
|
|
1681
1690
|
);
|
|
1682
1691
|
expect(resultEntities.length).toEqual(100);
|
|
1683
1692
|
for (let i = 0; i < resultEntities.length - 1; i++) {
|
|
1684
|
-
expect(
|
|
1685
|
-
resultEntities[i
|
|
1686
|
-
)
|
|
1693
|
+
expect(resultEntities[i + 1][sort]).toBeGreaterThan(
|
|
1694
|
+
resultEntities[i][sort] ?? 0
|
|
1695
|
+
);
|
|
1687
1696
|
}
|
|
1688
1697
|
|
|
1689
1698
|
// Retrieving entities reverse sorted...
|
|
1690
1699
|
resultEntities = await nymph.getEntities(
|
|
1691
|
-
{ class: TestModel, sort
|
|
1700
|
+
{ class: TestModel, sort, reverse: true },
|
|
1692
1701
|
{ type: '&', match: ['name', '^Multi Test '] }
|
|
1693
1702
|
);
|
|
1694
1703
|
expect(resultEntities.length).toEqual(100);
|
|
1695
1704
|
for (let i = 0; i < resultEntities.length - 1; i++) {
|
|
1696
|
-
expect(resultEntities[i + 1][sort
|
|
1697
|
-
resultEntities[i][sort
|
|
1705
|
+
expect(resultEntities[i + 1][sort]).toBeLessThan(
|
|
1706
|
+
resultEntities[i][sort] ?? 0
|
|
1698
1707
|
);
|
|
1699
1708
|
}
|
|
1700
1709
|
}
|
|
1701
1710
|
});
|
|
1702
1711
|
|
|
1712
|
+
it('property sort option', async () => {
|
|
1713
|
+
await createMultipleTestEntities();
|
|
1714
|
+
|
|
1715
|
+
// Retrieving entities sorted...
|
|
1716
|
+
let resultEntities = await nymph.getEntities({
|
|
1717
|
+
class: TestModel,
|
|
1718
|
+
sort: 'number',
|
|
1719
|
+
});
|
|
1720
|
+
expect(resultEntities.length).toBeGreaterThan(100);
|
|
1721
|
+
for (let i = 0; i < resultEntities.length - 1; i++) {
|
|
1722
|
+
expect(resultEntities[i + 1].number ?? Infinity).toBeGreaterThanOrEqual(
|
|
1723
|
+
resultEntities[i].number ?? 0
|
|
1724
|
+
);
|
|
1725
|
+
}
|
|
1726
|
+
|
|
1727
|
+
// And test the same with guid return...
|
|
1728
|
+
let resultGuids = await nymph.getEntities({
|
|
1729
|
+
class: TestModel,
|
|
1730
|
+
sort: 'number',
|
|
1731
|
+
return: 'guid',
|
|
1732
|
+
});
|
|
1733
|
+
expect(resultGuids.length).toBeGreaterThan(100);
|
|
1734
|
+
for (let i = 0; i < resultGuids.length - 1; i++) {
|
|
1735
|
+
expect(resultGuids[i]).toEqual(resultEntities[i].guid);
|
|
1736
|
+
}
|
|
1737
|
+
|
|
1738
|
+
// Retrieving entities reverse sorted...
|
|
1739
|
+
resultEntities = await nymph.getEntities({
|
|
1740
|
+
class: TestModel,
|
|
1741
|
+
sort: 'number',
|
|
1742
|
+
reverse: true,
|
|
1743
|
+
});
|
|
1744
|
+
expect(resultEntities.length).toBeGreaterThan(100);
|
|
1745
|
+
for (let i = 0; i < resultEntities.length - 1; i++) {
|
|
1746
|
+
expect(resultEntities[i + 1].number ?? 0).toBeLessThanOrEqual(
|
|
1747
|
+
resultEntities[i].number ?? Infinity
|
|
1748
|
+
);
|
|
1749
|
+
}
|
|
1750
|
+
|
|
1751
|
+
// And again with other selectors.
|
|
1752
|
+
// Retrieving entities sorted...
|
|
1753
|
+
resultEntities = await nymph.getEntities(
|
|
1754
|
+
{ class: TestModel, sort: 'number' },
|
|
1755
|
+
{ type: '&', match: ['name', '^Multi Test '] }
|
|
1756
|
+
);
|
|
1757
|
+
expect(resultEntities.length).toEqual(100);
|
|
1758
|
+
for (let i = 0; i < resultEntities.length - 1; i++) {
|
|
1759
|
+
expect(resultEntities[i + 1].number ?? Infinity).toBeGreaterThan(
|
|
1760
|
+
resultEntities[i].number ?? 0
|
|
1761
|
+
);
|
|
1762
|
+
expect(resultEntities[i].name).toEqual(
|
|
1763
|
+
`Multi Test ${100 - (resultEntities[i].number ?? 0)}`
|
|
1764
|
+
);
|
|
1765
|
+
}
|
|
1766
|
+
|
|
1767
|
+
// Retrieving entities reverse sorted...
|
|
1768
|
+
resultEntities = await nymph.getEntities(
|
|
1769
|
+
{ class: TestModel, sort: 'number', reverse: true },
|
|
1770
|
+
{ type: '&', match: ['name', '^Multi Test '] }
|
|
1771
|
+
);
|
|
1772
|
+
expect(resultEntities.length).toEqual(100);
|
|
1773
|
+
for (let i = 0; i < resultEntities.length - 1; i++) {
|
|
1774
|
+
expect(resultEntities[i + 1].number ?? 0).toBeLessThan(
|
|
1775
|
+
resultEntities[i].number ?? Infinity
|
|
1776
|
+
);
|
|
1777
|
+
expect(resultEntities[i].name).toEqual(
|
|
1778
|
+
`Multi Test ${100 - (resultEntities[i].number ?? 0)}`
|
|
1779
|
+
);
|
|
1780
|
+
}
|
|
1781
|
+
});
|
|
1782
|
+
|
|
1703
1783
|
it('delete reference', async () => {
|
|
1704
1784
|
await createTestEntities();
|
|
1705
1785
|
|
|
1706
1786
|
// Deleting referenced entities...
|
|
1787
|
+
await testEntity.reference?.$wake();
|
|
1707
1788
|
expect(await testEntity.reference?.$delete()).toEqual(true);
|
|
1789
|
+
await Promise.all(testEntity.refArray?.map((e) => e.$wake()) || []);
|
|
1708
1790
|
expect(testEntity.reference?.guid).toBeNull();
|
|
1709
1791
|
});
|
|
1710
1792
|
|
|
@@ -1728,9 +1810,6 @@ export function UIDTest(
|
|
|
1728
1810
|
nymph: Nymph,
|
|
1729
1811
|
it: (name: string, fn: () => void) => void
|
|
1730
1812
|
) {
|
|
1731
|
-
nymph.addEntityClass(TestModel);
|
|
1732
|
-
nymph.addEntityClass(TestBModel);
|
|
1733
|
-
|
|
1734
1813
|
it('delete old test data', async () => {
|
|
1735
1814
|
expect(await nymph.deleteUID('TestUID')).toEqual(true);
|
|
1736
1815
|
expect(await nymph.deleteUID('NewUID')).toEqual(true);
|
|
@@ -1772,8 +1851,8 @@ export function ExportImportTest(
|
|
|
1772
1851
|
nymph: Nymph,
|
|
1773
1852
|
it: (name: string, fn: () => void) => void
|
|
1774
1853
|
) {
|
|
1775
|
-
nymph.addEntityClass(
|
|
1776
|
-
nymph.addEntityClass(
|
|
1854
|
+
const TestModel = nymph.addEntityClass(TestModelClass);
|
|
1855
|
+
const TestBModel = nymph.addEntityClass(TestBModelClass);
|
|
1777
1856
|
|
|
1778
1857
|
async function deleteTestData() {
|
|
1779
1858
|
let all = await nymph.getEntities({ class: TestModel });
|
|
@@ -1817,9 +1896,11 @@ export function ExportImportTest(
|
|
|
1817
1896
|
expect(model.number).toEqual(30);
|
|
1818
1897
|
expect(model.timestamp).toBeGreaterThanOrEqual(strtotime('-2 minutes'));
|
|
1819
1898
|
|
|
1899
|
+
await model.reference?.$wake();
|
|
1820
1900
|
expect(model.reference?.guid).not.toBeNull();
|
|
1821
1901
|
expect(model.reference?.string).toEqual('another');
|
|
1822
1902
|
expect(model.reference?.index?.match(/^\d+b$/)).toBeTruthy();
|
|
1903
|
+
await Promise.all(model.refArray?.map((e) => e.$wake()) || []);
|
|
1823
1904
|
expect(model.refArray?.[0].guid).not.toBeNull();
|
|
1824
1905
|
expect(model.refArray?.[0].guid).toEqual(model.reference?.guid);
|
|
1825
1906
|
}
|
package/src/errors/index.ts
CHANGED
package/src/testArtifacts.ts
CHANGED
|
@@ -38,17 +38,15 @@ export class TestModel extends Entity<TestModelData> {
|
|
|
38
38
|
return (await super.factory(guid)) as TestModel & TestModelData;
|
|
39
39
|
}
|
|
40
40
|
|
|
41
|
-
static factorySync(
|
|
42
|
-
return super.factorySync(
|
|
41
|
+
static factorySync(): TestModel & TestModelData {
|
|
42
|
+
return super.factorySync() as TestModel & TestModelData;
|
|
43
43
|
}
|
|
44
44
|
|
|
45
|
-
constructor(
|
|
46
|
-
super(
|
|
45
|
+
constructor() {
|
|
46
|
+
super();
|
|
47
47
|
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
this.$data.boolean = true;
|
|
51
|
-
}
|
|
48
|
+
this.$addTag('test');
|
|
49
|
+
this.$data.boolean = true;
|
|
52
50
|
}
|
|
53
51
|
|
|
54
52
|
public $useProtectedData() {
|
|
@@ -82,7 +80,27 @@ export class TestBModel extends TestModel {
|
|
|
82
80
|
return (await super.factory(guid)) as TestBModel & TestModelData;
|
|
83
81
|
}
|
|
84
82
|
|
|
85
|
-
static factorySync(
|
|
86
|
-
return super.factorySync(
|
|
83
|
+
static factorySync(): TestBModel & TestModelData {
|
|
84
|
+
return super.factorySync() as TestBModel & TestModelData;
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
export type TestEmptyModelData = {};
|
|
89
|
+
|
|
90
|
+
/**
|
|
91
|
+
* This class is a test class that extends the Entity class.
|
|
92
|
+
*/
|
|
93
|
+
export class TestEmptyModel extends Entity<TestEmptyModelData> {
|
|
94
|
+
static ETYPE = 'test_empty_model';
|
|
95
|
+
static class = 'TestEmptyModel';
|
|
96
|
+
|
|
97
|
+
static async factory(
|
|
98
|
+
guid?: string
|
|
99
|
+
): Promise<TestEmptyModel & TestEmptyModelData> {
|
|
100
|
+
return (await super.factory(guid)) as TestEmptyModel & TestEmptyModelData;
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
static factorySync(): TestEmptyModel & TestEmptyModelData {
|
|
104
|
+
return super.factorySync() as TestEmptyModel & TestEmptyModelData;
|
|
87
105
|
}
|
|
88
106
|
}
|