@nymphjs/nymph 1.0.0-beta.124 → 1.0.0-beta.126
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 +12 -0
- package/dist/Entity.d.ts +1 -1
- package/dist/Entity.js +23 -23
- package/dist/Entity.js.map +1 -1
- package/dist/Entity.test.js +4 -4
- package/dist/Entity.test.js.map +1 -1
- package/dist/Entity.types.d.ts +12 -2
- package/dist/driver/NymphDriver.js +18 -7
- package/dist/driver/NymphDriver.js.map +1 -1
- package/dist/driver/testArtifacts.js +2 -1
- package/dist/driver/testArtifacts.js.map +1 -1
- package/dist/testMocks.js +4 -4
- package/dist/testMocks.js.map +1 -1
- package/dist/utils.d.ts +1 -1
- package/dist/utils.js +40 -33
- package/dist/utils.js.map +1 -1
- package/package.json +3 -3
- package/src/Entity.test.ts +4 -4
- package/src/Entity.ts +47 -34
- package/src/Entity.types.ts +12 -2
- package/src/driver/NymphDriver.ts +73 -7
- package/src/driver/testArtifacts.ts +7 -1
- package/src/testMocks.ts +28 -5
- package/src/utils.ts +47 -47
|
@@ -6,6 +6,7 @@ import { Tokenizer } from '@sciactive/tokenizer';
|
|
|
6
6
|
|
|
7
7
|
import type Nymph from '../Nymph.js';
|
|
8
8
|
import type { Selector, Options, FormattedSelector } from '../Nymph.types.js';
|
|
9
|
+
import Entity from '../Entity.js';
|
|
9
10
|
import type { EntityInstanceType, EntityObjectType } from '../Entity.js';
|
|
10
11
|
import type {
|
|
11
12
|
EntityConstructor,
|
|
@@ -19,7 +20,13 @@ import {
|
|
|
19
20
|
InvalidParametersError,
|
|
20
21
|
UnableToConnectError,
|
|
21
22
|
} from '../errors/index.js';
|
|
22
|
-
import {
|
|
23
|
+
import {
|
|
24
|
+
classNamesToEntityConstructors,
|
|
25
|
+
entitiesToReferences,
|
|
26
|
+
entityConstructorsToClassNames,
|
|
27
|
+
referencesToEntities,
|
|
28
|
+
xor,
|
|
29
|
+
} from '../utils.js';
|
|
23
30
|
|
|
24
31
|
// from: https://stackoverflow.com/a/6969486/664915
|
|
25
32
|
function escapeRegExp(string: string): string {
|
|
@@ -735,8 +742,19 @@ export default abstract class NymphDriver {
|
|
|
735
742
|
) {
|
|
736
743
|
return true;
|
|
737
744
|
}
|
|
745
|
+
if (
|
|
746
|
+
value instanceof Entity &&
|
|
747
|
+
value.guid != null &&
|
|
748
|
+
guids.indexOf(value.guid) !== -1
|
|
749
|
+
) {
|
|
750
|
+
return true;
|
|
751
|
+
}
|
|
738
752
|
// Search through arrays and objects looking for the reference.
|
|
739
|
-
if (
|
|
753
|
+
if (
|
|
754
|
+
value != null &&
|
|
755
|
+
(Array.isArray(value) ||
|
|
756
|
+
(typeof value === 'object' && !(value instanceof Entity)))
|
|
757
|
+
) {
|
|
740
758
|
for (const key in value) {
|
|
741
759
|
if (this.entityReferenceSearch(value[key], guids)) {
|
|
742
760
|
return true;
|
|
@@ -1328,7 +1346,20 @@ export default abstract class NymphDriver {
|
|
|
1328
1346
|
entity.cdate = cdate;
|
|
1329
1347
|
entity.mdate = mdate;
|
|
1330
1348
|
entity.tags = tags;
|
|
1331
|
-
entity.$putData(
|
|
1349
|
+
entity.$putData(
|
|
1350
|
+
classNamesToEntityConstructors(
|
|
1351
|
+
this.nymph,
|
|
1352
|
+
referencesToEntities(
|
|
1353
|
+
data,
|
|
1354
|
+
this.nymph,
|
|
1355
|
+
!!options.skipAc,
|
|
1356
|
+
false,
|
|
1357
|
+
),
|
|
1358
|
+
false,
|
|
1359
|
+
),
|
|
1360
|
+
sdata,
|
|
1361
|
+
'server',
|
|
1362
|
+
);
|
|
1332
1363
|
return {
|
|
1333
1364
|
result: Promise.resolve(null),
|
|
1334
1365
|
process: () => [entity],
|
|
@@ -1446,11 +1477,29 @@ export default abstract class NymphDriver {
|
|
|
1446
1477
|
cdate,
|
|
1447
1478
|
mdate,
|
|
1448
1479
|
tags,
|
|
1449
|
-
...
|
|
1480
|
+
...classNamesToEntityConstructors(
|
|
1481
|
+
this.nymph,
|
|
1482
|
+
referencesToEntities(
|
|
1483
|
+
data,
|
|
1484
|
+
this.nymph,
|
|
1485
|
+
!!options.skipAc,
|
|
1486
|
+
false,
|
|
1487
|
+
),
|
|
1488
|
+
false,
|
|
1489
|
+
),
|
|
1450
1490
|
...Object.fromEntries(
|
|
1451
1491
|
Object.entries(sdata).map(([name, value]) => [
|
|
1452
1492
|
name,
|
|
1453
|
-
|
|
1493
|
+
classNamesToEntityConstructors(
|
|
1494
|
+
this.nymph,
|
|
1495
|
+
referencesToEntities(
|
|
1496
|
+
JSON.parse(value),
|
|
1497
|
+
this.nymph,
|
|
1498
|
+
!!options.skipAc,
|
|
1499
|
+
false,
|
|
1500
|
+
),
|
|
1501
|
+
false,
|
|
1502
|
+
),
|
|
1454
1503
|
]),
|
|
1455
1504
|
),
|
|
1456
1505
|
} as EntityObjectType<T>);
|
|
@@ -1469,7 +1518,20 @@ export default abstract class NymphDriver {
|
|
|
1469
1518
|
if (this.putDataCounter == 100) {
|
|
1470
1519
|
throw new Error('Infinite loop detected in Entity loading.');
|
|
1471
1520
|
}
|
|
1472
|
-
entity.$putData(
|
|
1521
|
+
entity.$putData(
|
|
1522
|
+
classNamesToEntityConstructors(
|
|
1523
|
+
this.nymph,
|
|
1524
|
+
referencesToEntities(
|
|
1525
|
+
data,
|
|
1526
|
+
this.nymph,
|
|
1527
|
+
!!options.skipAc,
|
|
1528
|
+
false,
|
|
1529
|
+
),
|
|
1530
|
+
false,
|
|
1531
|
+
),
|
|
1532
|
+
sdata,
|
|
1533
|
+
'server',
|
|
1534
|
+
);
|
|
1473
1535
|
this.putDataCounter--;
|
|
1474
1536
|
entities.push(entity);
|
|
1475
1537
|
}
|
|
@@ -1537,7 +1599,11 @@ export default abstract class NymphDriver {
|
|
|
1537
1599
|
}
|
|
1538
1600
|
}
|
|
1539
1601
|
const tags = difference(entity.tags, ['']);
|
|
1540
|
-
const data =
|
|
1602
|
+
const data = entityConstructorsToClassNames(
|
|
1603
|
+
// Explicitly save references to entities that aren't saved yet to help
|
|
1604
|
+
// save circular references by saving with a guaranteed GUID.
|
|
1605
|
+
entitiesToReferences(entity.$getData(), false),
|
|
1606
|
+
);
|
|
1541
1607
|
const sdata = entity.$getSData();
|
|
1542
1608
|
const uniques = await entity.$getUniques();
|
|
1543
1609
|
const EntityClass = entity.constructor as EntityConstructor;
|
|
@@ -15,6 +15,10 @@ import {
|
|
|
15
15
|
TestModelData,
|
|
16
16
|
TestEmptyModel as TestEmptyModelClass,
|
|
17
17
|
} from '../testArtifacts.js';
|
|
18
|
+
import {
|
|
19
|
+
entitiesToReferences,
|
|
20
|
+
entityConstructorsToClassNames,
|
|
21
|
+
} from '../utils.js';
|
|
18
22
|
|
|
19
23
|
const __dirname = dirname(fileURLToPath(import.meta.url));
|
|
20
24
|
|
|
@@ -2706,7 +2710,9 @@ export function ExportImportTest(
|
|
|
2706
2710
|
expect(model).not.toBeNull();
|
|
2707
2711
|
|
|
2708
2712
|
if (model != null) {
|
|
2709
|
-
const data =
|
|
2713
|
+
const data = entityConstructorsToClassNames(
|
|
2714
|
+
entitiesToReferences(model.$getData(true), true),
|
|
2715
|
+
);
|
|
2710
2716
|
// These should not actually be saved in the DB.
|
|
2711
2717
|
data.number = 424242424242;
|
|
2712
2718
|
// But this should become searchable.
|
package/src/testMocks.ts
CHANGED
|
@@ -10,6 +10,12 @@ import type {
|
|
|
10
10
|
import { Options, Selector } from './Nymph.types.js';
|
|
11
11
|
import { ClassNotAvailableError, EntityConflictError } from './errors/index.js';
|
|
12
12
|
import Entity from './Entity.js';
|
|
13
|
+
import {
|
|
14
|
+
classNamesToEntityConstructors,
|
|
15
|
+
entitiesToReferences,
|
|
16
|
+
entityConstructorsToClassNames,
|
|
17
|
+
referencesToEntities,
|
|
18
|
+
} from './utils.js';
|
|
13
19
|
|
|
14
20
|
const entities: { [k: string]: EntityJson } = {};
|
|
15
21
|
|
|
@@ -62,7 +68,20 @@ export class MockNymphDriver {
|
|
|
62
68
|
entity.cdate = entityJson.cdate;
|
|
63
69
|
entity.mdate = entityJson.mdate;
|
|
64
70
|
entity.tags = entityJson.tags;
|
|
65
|
-
entity.$putData(
|
|
71
|
+
entity.$putData(
|
|
72
|
+
classNamesToEntityConstructors(
|
|
73
|
+
this.nymph as unknown as Nymph,
|
|
74
|
+
referencesToEntities(
|
|
75
|
+
entityJson.data,
|
|
76
|
+
this.nymph as unknown as Nymph,
|
|
77
|
+
!!options.skipAc,
|
|
78
|
+
false,
|
|
79
|
+
),
|
|
80
|
+
false,
|
|
81
|
+
),
|
|
82
|
+
{},
|
|
83
|
+
'server',
|
|
84
|
+
);
|
|
66
85
|
|
|
67
86
|
return entity as EntityInstanceType<T>;
|
|
68
87
|
}
|
|
@@ -154,8 +173,6 @@ export class MockNymph {
|
|
|
154
173
|
}
|
|
155
174
|
|
|
156
175
|
public async saveEntity(entity: EntityInterface): Promise<boolean> {
|
|
157
|
-
const className = (entity.constructor as any).class as string;
|
|
158
|
-
|
|
159
176
|
if (entity.guid == null) {
|
|
160
177
|
entity.guid = guid();
|
|
161
178
|
entity.cdate = Date.now();
|
|
@@ -171,12 +188,18 @@ export class MockNymph {
|
|
|
171
188
|
entity.mdate = Date.now();
|
|
172
189
|
|
|
173
190
|
const entityJson: EntityJson = {
|
|
174
|
-
class:
|
|
191
|
+
class: entity.constructor as EntityConstructor,
|
|
175
192
|
guid: entity.guid,
|
|
176
193
|
cdate: entity.cdate,
|
|
177
194
|
mdate: entity.mdate,
|
|
178
195
|
tags: [...entity.tags],
|
|
179
|
-
data: JSON.parse(
|
|
196
|
+
data: JSON.parse(
|
|
197
|
+
JSON.stringify(
|
|
198
|
+
entityConstructorsToClassNames(
|
|
199
|
+
entitiesToReferences(entity.$getData(true), true),
|
|
200
|
+
),
|
|
201
|
+
),
|
|
202
|
+
),
|
|
180
203
|
};
|
|
181
204
|
|
|
182
205
|
entities[entity.guid] = entityJson;
|
package/src/utils.ts
CHANGED
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
import Entity from './Entity.js';
|
|
2
2
|
import { EntityReference } from './Entity.types.js';
|
|
3
3
|
import Nymph from './Nymph.js';
|
|
4
|
-
import { Options, Selector } from './Nymph.types.js';
|
|
5
4
|
|
|
6
5
|
export function xor(a: any, b: any): boolean {
|
|
7
6
|
return !!(a && !b) || (!a && b);
|
|
@@ -15,6 +14,29 @@ export function uniqueStrings(array: string[]) {
|
|
|
15
14
|
return Object.keys(obj);
|
|
16
15
|
}
|
|
17
16
|
|
|
17
|
+
export function entityConstructorsToClassNames(item: any): any {
|
|
18
|
+
if (item == null || Buffer.isBuffer(item) || ArrayBuffer.isView(item)) {
|
|
19
|
+
return item;
|
|
20
|
+
} else if (typeof item === 'function' && item.prototype instanceof Entity) {
|
|
21
|
+
// Convert entity classes to class references.
|
|
22
|
+
return ['nymph_class_reference', item.class];
|
|
23
|
+
} else if (item instanceof Entity) {
|
|
24
|
+
// Don't touch entities.
|
|
25
|
+
return item;
|
|
26
|
+
} else if (Array.isArray(item)) {
|
|
27
|
+
// Recurse into lower arrays.
|
|
28
|
+
return item.map((entry) => entityConstructorsToClassNames(entry));
|
|
29
|
+
} else if (item instanceof Object) {
|
|
30
|
+
let newObj = Object.create(item);
|
|
31
|
+
for (let [key, value] of Object.entries(item)) {
|
|
32
|
+
newObj[key] = entityConstructorsToClassNames(value);
|
|
33
|
+
}
|
|
34
|
+
return newObj;
|
|
35
|
+
}
|
|
36
|
+
// Not an entity or array, just return it.
|
|
37
|
+
return item;
|
|
38
|
+
}
|
|
39
|
+
|
|
18
40
|
export function classNamesToEntityConstructors<T extends any>(
|
|
19
41
|
nymph: Nymph,
|
|
20
42
|
item: T,
|
|
@@ -34,12 +56,12 @@ export function classNamesToEntityConstructors<T extends any>(
|
|
|
34
56
|
throw new Error('Not accessible.');
|
|
35
57
|
}
|
|
36
58
|
return EntityClass as T;
|
|
37
|
-
} else if (
|
|
38
|
-
item instanceof Entity &&
|
|
39
|
-
typeof item.$toReference === 'function'
|
|
40
|
-
) {
|
|
59
|
+
} else if (item instanceof Entity) {
|
|
41
60
|
// Don't touch entities.
|
|
42
61
|
return item;
|
|
62
|
+
} else if (typeof item === 'function' && item.prototype instanceof Entity) {
|
|
63
|
+
// Don't touch Entity classes.
|
|
64
|
+
return item;
|
|
43
65
|
} else if (Array.isArray(item)) {
|
|
44
66
|
// Recurse into lower arrays.
|
|
45
67
|
return item.map((entry) =>
|
|
@@ -60,50 +82,13 @@ export function classNamesToEntityConstructors<T extends any>(
|
|
|
60
82
|
return item;
|
|
61
83
|
}
|
|
62
84
|
|
|
63
|
-
export function entityConstructorsToClassNames(item: any): any {
|
|
64
|
-
if (item == null || Buffer.isBuffer(item) || ArrayBuffer.isView(item)) {
|
|
65
|
-
return item;
|
|
66
|
-
} else if (
|
|
67
|
-
typeof item === 'function' &&
|
|
68
|
-
item.prototype instanceof Entity &&
|
|
69
|
-
typeof item.class === 'string'
|
|
70
|
-
) {
|
|
71
|
-
// Convert entity classes to class references.
|
|
72
|
-
return ['nymph_class_reference', item.class];
|
|
73
|
-
} else if (
|
|
74
|
-
item instanceof Entity &&
|
|
75
|
-
typeof item.$toReference === 'function'
|
|
76
|
-
) {
|
|
77
|
-
// Don't touch entities.
|
|
78
|
-
return item;
|
|
79
|
-
} else if (Array.isArray(item)) {
|
|
80
|
-
// Recurse into lower arrays.
|
|
81
|
-
return item.map((entry) => entityConstructorsToClassNames(entry));
|
|
82
|
-
} else if (item instanceof Object) {
|
|
83
|
-
let newObj = Object.create(item);
|
|
84
|
-
for (let [key, value] of Object.entries(item)) {
|
|
85
|
-
newObj[key] = entityConstructorsToClassNames(value);
|
|
86
|
-
}
|
|
87
|
-
return newObj;
|
|
88
|
-
}
|
|
89
|
-
// Not an entity or array, just return it.
|
|
90
|
-
return item;
|
|
91
|
-
}
|
|
92
|
-
|
|
93
85
|
export function entitiesToReferences(item: any, existingOnly?: boolean): any {
|
|
94
86
|
if (item == null || Buffer.isBuffer(item) || ArrayBuffer.isView(item)) {
|
|
95
87
|
return item;
|
|
96
|
-
} else if (
|
|
97
|
-
item instanceof Entity &&
|
|
98
|
-
typeof item.$toReference === 'function'
|
|
99
|
-
) {
|
|
88
|
+
} else if (item instanceof Entity) {
|
|
100
89
|
// Convert entities to references.
|
|
101
90
|
return item.$toReference(existingOnly);
|
|
102
|
-
} else if (
|
|
103
|
-
typeof item === 'function' &&
|
|
104
|
-
item.prototype instanceof Entity &&
|
|
105
|
-
typeof item.class === 'string'
|
|
106
|
-
) {
|
|
91
|
+
} else if (typeof item === 'function' && item.prototype instanceof Entity) {
|
|
107
92
|
// Don't touch Entity classes.
|
|
108
93
|
return item;
|
|
109
94
|
} else if (Array.isArray(item)) {
|
|
@@ -145,12 +130,27 @@ export function referencesToEntities(
|
|
|
145
130
|
}
|
|
146
131
|
} else {
|
|
147
132
|
// Recurse into lower arrays.
|
|
148
|
-
return item.map((entry) =>
|
|
133
|
+
return item.map((entry) =>
|
|
134
|
+
referencesToEntities(entry, nymph, useSkipAc, enforceRestEnabledFlag),
|
|
135
|
+
);
|
|
149
136
|
}
|
|
150
|
-
} else if (
|
|
137
|
+
} else if (item instanceof Entity) {
|
|
138
|
+
// Don't touch entities.
|
|
139
|
+
return item;
|
|
140
|
+
} else if (typeof item === 'function' && item.prototype instanceof Entity) {
|
|
141
|
+
// Don't touch Entity classes.
|
|
142
|
+
return item;
|
|
143
|
+
} else if (item instanceof Object) {
|
|
144
|
+
let newObj = Object.create(item);
|
|
151
145
|
for (let [key, value] of Object.entries(item)) {
|
|
152
|
-
|
|
146
|
+
newObj[key] = referencesToEntities(
|
|
147
|
+
value,
|
|
148
|
+
nymph,
|
|
149
|
+
useSkipAc,
|
|
150
|
+
enforceRestEnabledFlag,
|
|
151
|
+
);
|
|
153
152
|
}
|
|
153
|
+
return newObj;
|
|
154
154
|
}
|
|
155
155
|
// Not an array, just return it.
|
|
156
156
|
return item;
|