@nymphjs/nymph 1.0.0-beta.7 → 1.0.0-beta.71
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 +324 -0
- package/README.md +13 -21
- package/dist/Entity.d.ts +269 -7
- package/dist/Entity.js +491 -105
- package/dist/Entity.js.map +1 -1
- package/dist/Entity.test.js +39 -17
- package/dist/Entity.test.js.map +1 -1
- package/dist/Entity.types.d.ts +225 -19
- package/dist/Nymph.d.ts +423 -11
- package/dist/Nymph.js +685 -176
- package/dist/Nymph.js.map +1 -1
- package/dist/Nymph.types.d.ts +31 -7
- package/dist/Nymph.types.js +2 -1
- package/dist/Nymph.types.js.map +1 -1
- package/dist/conf/d.d.ts +26 -0
- package/dist/conf/defaults.js +22 -0
- package/dist/conf/defaults.js.map +1 -1
- package/dist/driver/NymphDriver.d.ts +129 -38
- package/dist/driver/NymphDriver.js +264 -131
- package/dist/driver/NymphDriver.js.map +1 -1
- package/dist/driver/testArtifacts.d.ts +1 -1
- package/dist/driver/testArtifacts.js +336 -42
- package/dist/driver/testArtifacts.js.map +1 -1
- package/dist/errors/EntityInvalidDataError.d.ts +6 -0
- package/dist/errors/EntityInvalidDataError.js +7 -1
- package/dist/errors/EntityInvalidDataError.js.map +1 -1
- package/dist/errors/EntityUniqueConstraintError.d.ts +3 -0
- package/dist/errors/EntityUniqueConstraintError.js +11 -0
- package/dist/errors/EntityUniqueConstraintError.js.map +1 -0
- 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/QueryFailedError.js +1 -0
- package/dist/errors/QueryFailedError.js.map +1 -1
- package/dist/errors/index.d.ts +2 -0
- package/dist/errors/index.js +2 -0
- package/dist/errors/index.js.map +1 -1
- package/dist/testArtifacts.d.ts +17 -5
- package/dist/testArtifacts.js +31 -27
- package/dist/testArtifacts.js.map +1 -1
- package/dist/testMocks.d.ts +15 -10
- package/dist/testMocks.js +37 -13
- package/dist/testMocks.js.map +1 -1
- package/dist/utils.d.ts +1 -1
- package/dist/utils.js +21 -5
- package/dist/utils.js.map +1 -1
- package/package.json +16 -14
- package/src/Entity.test.ts +32 -11
- package/src/Entity.ts +423 -134
- package/src/Entity.types.ts +32 -66
- package/src/Nymph.ts +618 -195
- package/src/Nymph.types.ts +97 -26
- package/src/conf/d.ts +8 -0
- package/src/conf/defaults.ts +24 -0
- package/src/driver/NymphDriver.ts +281 -311
- package/src/driver/testArtifacts.ts +384 -173
- package/src/errors/EntityUniqueConstraintError.ts +6 -0
- package/src/errors/InvalidStateError.ts +6 -0
- package/src/errors/index.ts +4 -0
- package/src/nymphJoiProps.ts +2 -2
- package/src/testArtifacts.ts +18 -19
- package/src/testMocks.ts +64 -32
- package/src/utils.ts +22 -8
- package/tsconfig.json +3 -3
- package/typedoc.json +4 -0
package/src/Entity.ts
CHANGED
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
import { difference, intersection, isEqual } from 'lodash';
|
|
2
2
|
|
|
3
3
|
import type Nymph from './Nymph';
|
|
4
|
-
import {
|
|
4
|
+
import type { Options } from './Nymph.types';
|
|
5
|
+
import type {
|
|
5
6
|
ACProperties,
|
|
6
7
|
EntityConstructor,
|
|
7
8
|
EntityData,
|
|
@@ -11,13 +12,25 @@ import {
|
|
|
11
12
|
EntityReference,
|
|
12
13
|
SerializedEntityData,
|
|
13
14
|
} from './Entity.types';
|
|
14
|
-
import {
|
|
15
|
+
import {
|
|
16
|
+
EntityConflictError,
|
|
17
|
+
EntityIsSleepingReferenceError,
|
|
18
|
+
InvalidParametersError,
|
|
19
|
+
InvalidStateError,
|
|
20
|
+
} from './errors';
|
|
15
21
|
import {
|
|
16
22
|
entitiesToReferences,
|
|
17
23
|
referencesToEntities,
|
|
18
24
|
uniqueStrings,
|
|
19
25
|
} from './utils';
|
|
20
26
|
|
|
27
|
+
export type EntityDataType<T> = T extends Entity<infer DataType>
|
|
28
|
+
? DataType
|
|
29
|
+
: never;
|
|
30
|
+
|
|
31
|
+
export type EntityInstanceType<T extends EntityConstructor> =
|
|
32
|
+
T extends new () => infer E ? E & EntityDataType<E> : never;
|
|
33
|
+
|
|
21
34
|
/**
|
|
22
35
|
* Database abstraction object.
|
|
23
36
|
*
|
|
@@ -45,9 +58,9 @@ import {
|
|
|
45
58
|
*
|
|
46
59
|
* Some notes about $equals() and $is(), the replacements for "==":
|
|
47
60
|
*
|
|
48
|
-
* The == operator will likely not give you the result you want, since
|
|
49
|
-
*
|
|
50
|
-
*
|
|
61
|
+
* The == operator will likely not give you the result you want, since two
|
|
62
|
+
* instances of the same entity will fail that check, even though they represent
|
|
63
|
+
* the same data in the database.
|
|
51
64
|
*
|
|
52
65
|
* $equals() performs a more strict comparison of the entity to another. Use
|
|
53
66
|
* $equals() instead of the == operator when you want to check both the entities
|
|
@@ -56,8 +69,7 @@ import {
|
|
|
56
69
|
*
|
|
57
70
|
* - They must be entities.
|
|
58
71
|
* - They must have equal GUIDs, or both must have no GUID.
|
|
59
|
-
* -
|
|
60
|
-
* - Their data must be equal.
|
|
72
|
+
* - Their data and tags must be equal.
|
|
61
73
|
*
|
|
62
74
|
* $is() performs a less strict comparison of the entity to another. Use $is()
|
|
63
75
|
* instead of the == operator when the entity's data may have been changed, but
|
|
@@ -66,7 +78,7 @@ import {
|
|
|
66
78
|
*
|
|
67
79
|
* - They must be entities.
|
|
68
80
|
* - They must have equal GUIDs, or both must have no GUID.
|
|
69
|
-
* - If they have no GUIDs, their data must be equal.
|
|
81
|
+
* - If they have no GUIDs, their data and tags must be equal.
|
|
70
82
|
*
|
|
71
83
|
* Some notes about saving entities in other entity's properties:
|
|
72
84
|
*
|
|
@@ -137,6 +149,10 @@ export default class Entity<T extends EntityData = EntityData>
|
|
|
137
149
|
* The reference to use to wake.
|
|
138
150
|
*/
|
|
139
151
|
protected $sleepingReference: EntityReference | null = null;
|
|
152
|
+
/**
|
|
153
|
+
* A promise that resolved when the entity's data is wake.
|
|
154
|
+
*/
|
|
155
|
+
protected $wakePromise: Promise<Entity<T>> | null = null;
|
|
140
156
|
/**
|
|
141
157
|
* Properties that will not be serialized into JSON with toJSON(). This
|
|
142
158
|
* can be considered a denylist, because these properties will not be set
|
|
@@ -146,6 +162,18 @@ export default class Entity<T extends EntityData = EntityData>
|
|
|
146
162
|
* also listed in searchRestrictedData.
|
|
147
163
|
*/
|
|
148
164
|
protected $privateData: string[] = [];
|
|
165
|
+
/**
|
|
166
|
+
* Whether this entity should publish changes to PubSub servers.
|
|
167
|
+
*/
|
|
168
|
+
public static pubSubEnabled = true;
|
|
169
|
+
/**
|
|
170
|
+
* Whether this entity should be accessible on the frontend through the REST
|
|
171
|
+
* server.
|
|
172
|
+
*
|
|
173
|
+
* If this is false, any request from the client that attempts to use this
|
|
174
|
+
* entity will fail.
|
|
175
|
+
*/
|
|
176
|
+
public static restEnabled = true;
|
|
149
177
|
/**
|
|
150
178
|
* Properties that will not be searchable from the frontend. If the frontend
|
|
151
179
|
* includes any of these properties in any of their clauses, they will be
|
|
@@ -157,8 +185,20 @@ export default class Entity<T extends EntityData = EntityData>
|
|
|
157
185
|
* be visible on the frontend, unlike $privateData, but any changes to them
|
|
158
186
|
* that come from the frontend will be ignored.
|
|
159
187
|
*
|
|
160
|
-
* In addition to what's listed here, the
|
|
161
|
-
* be
|
|
188
|
+
* In addition to what's listed here, all of the access control properties
|
|
189
|
+
* will be included when Tilmeld is being used. These are:
|
|
190
|
+
*
|
|
191
|
+
* - acUser
|
|
192
|
+
* - acGroup
|
|
193
|
+
* - acOther
|
|
194
|
+
* - acRead
|
|
195
|
+
* - acWrite
|
|
196
|
+
* - acFull
|
|
197
|
+
* - user
|
|
198
|
+
* - group
|
|
199
|
+
*
|
|
200
|
+
* You should modify these through client enabled methods or the $save method
|
|
201
|
+
* instead, for safety.
|
|
162
202
|
*/
|
|
163
203
|
protected $protectedData: string[] = [];
|
|
164
204
|
/**
|
|
@@ -199,26 +239,33 @@ export default class Entity<T extends EntityData = EntityData>
|
|
|
199
239
|
private $originalAcValues: ACProperties | null = null;
|
|
200
240
|
|
|
201
241
|
/**
|
|
202
|
-
*
|
|
203
|
-
*
|
|
242
|
+
* Alter the options for a query for this entity.
|
|
243
|
+
*
|
|
244
|
+
* @param options The current options.
|
|
245
|
+
* @returns The altered options.
|
|
204
246
|
*/
|
|
205
|
-
|
|
247
|
+
static alterOptions?<T extends Options>(options: T): T;
|
|
248
|
+
|
|
249
|
+
/**
|
|
250
|
+
* Initialize an entity.
|
|
251
|
+
*/
|
|
252
|
+
public constructor(..._rest: any[]) {
|
|
206
253
|
this.$nymph = (this.constructor as EntityConstructor).nymph;
|
|
207
254
|
this.$dataHandler = {
|
|
208
255
|
has: (data: EntityData, name: string) => {
|
|
209
|
-
this.$
|
|
256
|
+
this.$check();
|
|
210
257
|
|
|
211
258
|
return name in data || name in this.$sdata;
|
|
212
259
|
},
|
|
213
260
|
|
|
214
261
|
get: (data: EntityData, name: string) => {
|
|
215
|
-
this.$
|
|
262
|
+
this.$check();
|
|
216
263
|
|
|
217
264
|
if (this.$sdata.hasOwnProperty(name)) {
|
|
218
265
|
data[name] = referencesToEntities(
|
|
219
266
|
JSON.parse(this.$sdata[name]),
|
|
220
267
|
this.$nymph,
|
|
221
|
-
this.$skipAc
|
|
268
|
+
this.$skipAc,
|
|
222
269
|
);
|
|
223
270
|
delete this.$sdata[name];
|
|
224
271
|
}
|
|
@@ -229,7 +276,7 @@ export default class Entity<T extends EntityData = EntityData>
|
|
|
229
276
|
},
|
|
230
277
|
|
|
231
278
|
set: (data: EntityData, name: string, value: any) => {
|
|
232
|
-
this.$
|
|
279
|
+
this.$check();
|
|
233
280
|
|
|
234
281
|
if (this.$sdata.hasOwnProperty(name)) {
|
|
235
282
|
delete this.$sdata[name];
|
|
@@ -239,7 +286,7 @@ export default class Entity<T extends EntityData = EntityData>
|
|
|
239
286
|
},
|
|
240
287
|
|
|
241
288
|
deleteProperty: (data: EntityData, name: string) => {
|
|
242
|
-
this.$
|
|
289
|
+
this.$check();
|
|
243
290
|
|
|
244
291
|
if (this.$sdata.hasOwnProperty(name)) {
|
|
245
292
|
return delete this.$sdata[name];
|
|
@@ -253,9 +300,9 @@ export default class Entity<T extends EntityData = EntityData>
|
|
|
253
300
|
defineProperty: (
|
|
254
301
|
data: EntityData,
|
|
255
302
|
name: string,
|
|
256
|
-
descriptor: PropertyDescriptor
|
|
303
|
+
descriptor: PropertyDescriptor,
|
|
257
304
|
) => {
|
|
258
|
-
this.$
|
|
305
|
+
this.$check();
|
|
259
306
|
|
|
260
307
|
if (this.$sdata.hasOwnProperty(name)) {
|
|
261
308
|
delete this.$sdata[name];
|
|
@@ -265,13 +312,13 @@ export default class Entity<T extends EntityData = EntityData>
|
|
|
265
312
|
},
|
|
266
313
|
|
|
267
314
|
getOwnPropertyDescriptor: (data: EntityData, name: string) => {
|
|
268
|
-
this.$
|
|
315
|
+
this.$check();
|
|
269
316
|
|
|
270
317
|
if (this.$sdata.hasOwnProperty(name)) {
|
|
271
318
|
data[name] = referencesToEntities(
|
|
272
319
|
JSON.parse(this.$sdata[name]),
|
|
273
320
|
this.$nymph,
|
|
274
|
-
this.$skipAc
|
|
321
|
+
this.$skipAc,
|
|
275
322
|
);
|
|
276
323
|
delete this.$sdata[name];
|
|
277
324
|
}
|
|
@@ -279,10 +326,10 @@ export default class Entity<T extends EntityData = EntityData>
|
|
|
279
326
|
},
|
|
280
327
|
|
|
281
328
|
ownKeys: (data: EntityData) => {
|
|
282
|
-
this.$
|
|
329
|
+
this.$check();
|
|
283
330
|
|
|
284
331
|
return Object.getOwnPropertyNames(data).concat(
|
|
285
|
-
Object.getOwnPropertyNames(this.$sdata)
|
|
332
|
+
Object.getOwnPropertyNames(this.$sdata),
|
|
286
333
|
);
|
|
287
334
|
},
|
|
288
335
|
};
|
|
@@ -291,20 +338,6 @@ export default class Entity<T extends EntityData = EntityData>
|
|
|
291
338
|
|
|
292
339
|
this.$data = new Proxy(this.$dataStore, this.$dataHandler);
|
|
293
340
|
|
|
294
|
-
if (guid != null) {
|
|
295
|
-
const entity = this.$nymph.driver.getEntitySync(
|
|
296
|
-
{ class: this.constructor as EntityConstructor },
|
|
297
|
-
{ type: '&', guid }
|
|
298
|
-
);
|
|
299
|
-
if (entity) {
|
|
300
|
-
this.guid = entity.guid;
|
|
301
|
-
this.tags = entity.tags;
|
|
302
|
-
this.cdate = entity.cdate;
|
|
303
|
-
this.mdate = entity.mdate;
|
|
304
|
-
this.$putData(entity.$getData(), entity.$getSData());
|
|
305
|
-
}
|
|
306
|
-
}
|
|
307
|
-
|
|
308
341
|
return new Proxy(this, {
|
|
309
342
|
has: (entity: Entity, name: string) => {
|
|
310
343
|
if (
|
|
@@ -315,7 +348,7 @@ export default class Entity<T extends EntityData = EntityData>
|
|
|
315
348
|
return name in entity;
|
|
316
349
|
}
|
|
317
350
|
|
|
318
|
-
this.$
|
|
351
|
+
this.$check();
|
|
319
352
|
return name in entity.$data;
|
|
320
353
|
},
|
|
321
354
|
|
|
@@ -326,12 +359,12 @@ export default class Entity<T extends EntityData = EntityData>
|
|
|
326
359
|
name.substring(0, 1) === '$'
|
|
327
360
|
) {
|
|
328
361
|
if (name === 'tags' || name === 'cdate' || name === 'mdate') {
|
|
329
|
-
this.$
|
|
362
|
+
this.$check();
|
|
330
363
|
}
|
|
331
364
|
return (entity as any)[name];
|
|
332
365
|
}
|
|
333
366
|
|
|
334
|
-
this.$
|
|
367
|
+
this.$check();
|
|
335
368
|
if (name in entity.$data) {
|
|
336
369
|
return entity.$data[name];
|
|
337
370
|
}
|
|
@@ -345,11 +378,11 @@ export default class Entity<T extends EntityData = EntityData>
|
|
|
345
378
|
name.substring(0, 1) === '$'
|
|
346
379
|
) {
|
|
347
380
|
if (name === 'tags' || name === 'cdate' || name === 'mdate') {
|
|
348
|
-
this.$
|
|
381
|
+
this.$check();
|
|
349
382
|
}
|
|
350
383
|
(entity as any)[name] = value;
|
|
351
384
|
} else {
|
|
352
|
-
this.$
|
|
385
|
+
this.$check();
|
|
353
386
|
(entity.$data as any)[name] = value;
|
|
354
387
|
}
|
|
355
388
|
return true;
|
|
@@ -359,7 +392,7 @@ export default class Entity<T extends EntityData = EntityData>
|
|
|
359
392
|
if (name in entity) {
|
|
360
393
|
return delete (entity as any)[name];
|
|
361
394
|
} else if (name in entity.$data) {
|
|
362
|
-
this.$
|
|
395
|
+
this.$check();
|
|
363
396
|
return delete entity.$data[name];
|
|
364
397
|
}
|
|
365
398
|
return true;
|
|
@@ -372,7 +405,7 @@ export default class Entity<T extends EntityData = EntityData>
|
|
|
372
405
|
defineProperty: (
|
|
373
406
|
entity: Entity,
|
|
374
407
|
name: string,
|
|
375
|
-
descriptor: PropertyDescriptor
|
|
408
|
+
descriptor: PropertyDescriptor,
|
|
376
409
|
) => {
|
|
377
410
|
if (
|
|
378
411
|
typeof name !== 'string' ||
|
|
@@ -380,11 +413,11 @@ export default class Entity<T extends EntityData = EntityData>
|
|
|
380
413
|
name.substring(0, 1) === '$'
|
|
381
414
|
) {
|
|
382
415
|
if (name === 'tags' || name === 'cdate' || name === 'mdate') {
|
|
383
|
-
this.$
|
|
416
|
+
this.$check();
|
|
384
417
|
}
|
|
385
418
|
Object.defineProperty(entity, name, descriptor);
|
|
386
419
|
} else {
|
|
387
|
-
this.$
|
|
420
|
+
this.$check();
|
|
388
421
|
Object.defineProperty(entity.$data, name, descriptor);
|
|
389
422
|
}
|
|
390
423
|
return true;
|
|
@@ -397,48 +430,126 @@ export default class Entity<T extends EntityData = EntityData>
|
|
|
397
430
|
name.substring(0, 1) === '$'
|
|
398
431
|
) {
|
|
399
432
|
if (name === 'tags' || name === 'cdate' || name === 'mdate') {
|
|
400
|
-
this.$
|
|
433
|
+
this.$check();
|
|
401
434
|
}
|
|
402
435
|
return Object.getOwnPropertyDescriptor(entity, name);
|
|
403
436
|
} else {
|
|
404
|
-
this.$
|
|
437
|
+
this.$check();
|
|
405
438
|
return Object.getOwnPropertyDescriptor(entity.$data, name);
|
|
406
439
|
}
|
|
407
440
|
},
|
|
408
441
|
|
|
409
442
|
ownKeys: (entity: Entity) => {
|
|
410
|
-
this.$
|
|
443
|
+
this.$check();
|
|
411
444
|
return Object.getOwnPropertyNames(entity).concat(
|
|
412
|
-
Object.getOwnPropertyNames(entity.$data)
|
|
445
|
+
Object.getOwnPropertyNames(entity.$data),
|
|
413
446
|
);
|
|
414
447
|
},
|
|
415
448
|
}) as Entity<T>;
|
|
416
449
|
}
|
|
417
450
|
|
|
418
|
-
|
|
451
|
+
/**
|
|
452
|
+
* Create or retrieve a new entity instance.
|
|
453
|
+
*
|
|
454
|
+
* Note that this will always return an entity, even if the GUID is not found.
|
|
455
|
+
*
|
|
456
|
+
* @param guid An optional GUID to retrieve.
|
|
457
|
+
*/
|
|
458
|
+
public static async factory<E extends Entity>(
|
|
459
|
+
this: {
|
|
460
|
+
new (): E;
|
|
461
|
+
},
|
|
462
|
+
guid?: string,
|
|
463
|
+
): Promise<E & EntityDataType<E>> {
|
|
419
464
|
const entity = new this();
|
|
420
465
|
if (guid != null) {
|
|
421
|
-
const entity = await
|
|
466
|
+
const entity = await (
|
|
467
|
+
this as unknown as EntityConstructor
|
|
468
|
+
).nymph.getEntity(
|
|
422
469
|
{
|
|
423
|
-
class: this as
|
|
470
|
+
class: this as unknown as EntityConstructor,
|
|
424
471
|
},
|
|
425
|
-
{ type: '&', guid }
|
|
472
|
+
{ type: '&', guid },
|
|
426
473
|
);
|
|
427
474
|
if (entity != null) {
|
|
428
|
-
return entity
|
|
475
|
+
return entity as E & EntityDataType<E>;
|
|
429
476
|
}
|
|
430
477
|
}
|
|
431
|
-
return entity
|
|
478
|
+
return entity as E & EntityDataType<E>;
|
|
432
479
|
}
|
|
433
480
|
|
|
434
|
-
|
|
435
|
-
|
|
481
|
+
/**
|
|
482
|
+
* Create a new entity instance.
|
|
483
|
+
*/
|
|
484
|
+
public static factorySync<E extends Entity>(this: {
|
|
485
|
+
new (): E;
|
|
486
|
+
}): E & EntityDataType<E> {
|
|
487
|
+
return new this() as E & EntityDataType<E>;
|
|
436
488
|
}
|
|
437
489
|
|
|
438
|
-
|
|
490
|
+
/**
|
|
491
|
+
* Create a new sleeping reference instance.
|
|
492
|
+
*
|
|
493
|
+
* Sleeping references won't retrieve their data from the database until they
|
|
494
|
+
* are readied with `$wake()` or a parent's `$wakeAll()`.
|
|
495
|
+
*
|
|
496
|
+
* @param reference The Nymph Entity Reference to use to wake.
|
|
497
|
+
* @returns The new instance.
|
|
498
|
+
*/
|
|
499
|
+
public static factoryReference<E extends Entity>(
|
|
500
|
+
this: {
|
|
501
|
+
new (): E;
|
|
502
|
+
},
|
|
503
|
+
reference: EntityReference,
|
|
504
|
+
): E & EntityDataType<E> {
|
|
439
505
|
const entity = new this();
|
|
440
506
|
entity.$referenceSleep(reference);
|
|
441
|
-
return entity
|
|
507
|
+
return entity as E & EntityDataType<E>;
|
|
508
|
+
}
|
|
509
|
+
|
|
510
|
+
/**
|
|
511
|
+
* Get an array of strings that **must** be unique across the current etype.
|
|
512
|
+
*
|
|
513
|
+
* When you try to save another entity with any of the same unique strings,
|
|
514
|
+
* Nymph will throw an error.
|
|
515
|
+
*
|
|
516
|
+
* The default implementation of this static method instantiates the entity,
|
|
517
|
+
* assigns all of the given data, then calls `$getUniques` and returns its
|
|
518
|
+
* output. This can have a performance impact if a lot of extra processing
|
|
519
|
+
* happens during any of these steps. You can override this method to
|
|
520
|
+
* calculate the unique strings faster, but you must return the same strings
|
|
521
|
+
* that would be returned by `$getUniques`.
|
|
522
|
+
*
|
|
523
|
+
* @returns Resolves to an array of entity's unique constraint strings.
|
|
524
|
+
*/
|
|
525
|
+
public static async getUniques({
|
|
526
|
+
guid,
|
|
527
|
+
cdate,
|
|
528
|
+
mdate,
|
|
529
|
+
tags,
|
|
530
|
+
data,
|
|
531
|
+
sdata,
|
|
532
|
+
}: {
|
|
533
|
+
guid?: string;
|
|
534
|
+
cdate?: number;
|
|
535
|
+
mdate?: number;
|
|
536
|
+
tags: string[];
|
|
537
|
+
data: EntityData;
|
|
538
|
+
sdata?: SerializedEntityData;
|
|
539
|
+
}) {
|
|
540
|
+
const entity = new this();
|
|
541
|
+
if (guid != null) {
|
|
542
|
+
entity.guid = guid;
|
|
543
|
+
}
|
|
544
|
+
if (cdate != null) {
|
|
545
|
+
entity.cdate = cdate;
|
|
546
|
+
}
|
|
547
|
+
if (mdate != null) {
|
|
548
|
+
entity.mdate = mdate;
|
|
549
|
+
}
|
|
550
|
+
entity.tags = tags;
|
|
551
|
+
entity.$putData(data, sdata);
|
|
552
|
+
return await entity.$getUniques();
|
|
442
553
|
}
|
|
443
554
|
|
|
444
555
|
public toJSON() {
|
|
@@ -463,7 +574,7 @@ export default class Entity<T extends EntityData = EntityData>
|
|
|
463
574
|
}
|
|
464
575
|
|
|
465
576
|
public $addTag(...tags: string[]) {
|
|
466
|
-
this.$
|
|
577
|
+
this.$check();
|
|
467
578
|
|
|
468
579
|
if (tags.length < 1) {
|
|
469
580
|
return;
|
|
@@ -472,7 +583,7 @@ export default class Entity<T extends EntityData = EntityData>
|
|
|
472
583
|
}
|
|
473
584
|
|
|
474
585
|
public $arraySearch(array: any[], strict = false) {
|
|
475
|
-
this.$
|
|
586
|
+
this.$check();
|
|
476
587
|
|
|
477
588
|
if (!Array.isArray(array)) {
|
|
478
589
|
return -1;
|
|
@@ -487,7 +598,7 @@ export default class Entity<T extends EntityData = EntityData>
|
|
|
487
598
|
}
|
|
488
599
|
|
|
489
600
|
public $clearCache() {
|
|
490
|
-
this.$
|
|
601
|
+
this.$check();
|
|
491
602
|
|
|
492
603
|
this.$putData(this.$getData(), this.$getSData());
|
|
493
604
|
}
|
|
@@ -497,13 +608,13 @@ export default class Entity<T extends EntityData = EntityData>
|
|
|
497
608
|
}
|
|
498
609
|
|
|
499
610
|
public async $delete(): Promise<boolean> {
|
|
500
|
-
this.$
|
|
611
|
+
this.$check();
|
|
501
612
|
|
|
502
613
|
return await this.$nymph.deleteEntity(this);
|
|
503
614
|
}
|
|
504
615
|
|
|
505
616
|
public $equals(object: any) {
|
|
506
|
-
this.$
|
|
617
|
+
this.$check();
|
|
507
618
|
|
|
508
619
|
if (!(object instanceof Entity)) {
|
|
509
620
|
return false;
|
|
@@ -513,22 +624,24 @@ export default class Entity<T extends EntityData = EntityData>
|
|
|
513
624
|
return false;
|
|
514
625
|
}
|
|
515
626
|
}
|
|
516
|
-
if (object.constructor !== this.constructor) {
|
|
517
|
-
return false;
|
|
518
|
-
}
|
|
519
627
|
if (object.cdate !== this.cdate) {
|
|
520
628
|
return false;
|
|
521
629
|
}
|
|
522
630
|
if (object.mdate !== this.mdate) {
|
|
523
631
|
return false;
|
|
524
632
|
}
|
|
633
|
+
const obTags = [...object.tags].sort();
|
|
634
|
+
const myTags = [...this.tags].sort();
|
|
635
|
+
if (!isEqual(obTags, myTags)) {
|
|
636
|
+
return false;
|
|
637
|
+
}
|
|
525
638
|
const obData = object.$getData(true);
|
|
526
639
|
const myData = this.$getData(true);
|
|
527
640
|
return isEqual(obData, myData);
|
|
528
641
|
}
|
|
529
642
|
|
|
530
643
|
public $getData(includeSData = false) {
|
|
531
|
-
this.$
|
|
644
|
+
this.$check();
|
|
532
645
|
|
|
533
646
|
if (includeSData) {
|
|
534
647
|
// Access all the serialized properties to initialize them.
|
|
@@ -540,30 +653,75 @@ export default class Entity<T extends EntityData = EntityData>
|
|
|
540
653
|
}
|
|
541
654
|
|
|
542
655
|
public $getSData() {
|
|
543
|
-
this.$
|
|
656
|
+
this.$check();
|
|
544
657
|
|
|
545
658
|
return this.$sdata;
|
|
546
659
|
}
|
|
547
660
|
|
|
548
|
-
public $
|
|
549
|
-
|
|
661
|
+
public async $getUniques(): Promise<string[]> {
|
|
662
|
+
return [];
|
|
663
|
+
}
|
|
664
|
+
|
|
665
|
+
public $getOriginalAcValues(): ACProperties {
|
|
666
|
+
this.$check();
|
|
667
|
+
|
|
668
|
+
return this.$originalAcValues ?? this.$getCurrentAcValues();
|
|
669
|
+
}
|
|
670
|
+
|
|
671
|
+
public $getCurrentAcValues(): ACProperties {
|
|
672
|
+
this.$check();
|
|
673
|
+
|
|
674
|
+
return {
|
|
675
|
+
user: this.$getAcUid(),
|
|
676
|
+
group: this.$getAcGid(),
|
|
677
|
+
acUser: this.$data.acUser ?? null,
|
|
678
|
+
acGroup: this.$data.acGroup ?? null,
|
|
679
|
+
acOther: this.$data.acOther ?? null,
|
|
680
|
+
acRead: this.$getAcReadIds(),
|
|
681
|
+
acWrite: this.$getAcWriteIds(),
|
|
682
|
+
acFull: this.$getAcFullIds(),
|
|
683
|
+
};
|
|
684
|
+
}
|
|
550
685
|
|
|
551
|
-
|
|
552
|
-
|
|
553
|
-
|
|
554
|
-
|
|
555
|
-
|
|
556
|
-
|
|
557
|
-
|
|
558
|
-
|
|
559
|
-
acWrite: this.$data.acWrite,
|
|
560
|
-
acFull: this.$data.acFull,
|
|
686
|
+
public $getAcUid() {
|
|
687
|
+
if ('user' in this.$sdata) {
|
|
688
|
+
const userValue = JSON.parse(this.$sdata.user);
|
|
689
|
+
if (
|
|
690
|
+
Array.isArray(userValue) &&
|
|
691
|
+
userValue[0] === 'nymph_entity_reference'
|
|
692
|
+
) {
|
|
693
|
+
return userValue[1];
|
|
561
694
|
}
|
|
562
|
-
|
|
695
|
+
}
|
|
696
|
+
return (this.$data.user?.guid ?? null) as string | null;
|
|
697
|
+
}
|
|
698
|
+
public $getAcGid() {
|
|
699
|
+
if ('group' in this.$sdata) {
|
|
700
|
+
const groupValue = JSON.parse(this.$sdata.group);
|
|
701
|
+
if (
|
|
702
|
+
Array.isArray(groupValue) &&
|
|
703
|
+
groupValue[0] === 'nymph_entity_reference'
|
|
704
|
+
) {
|
|
705
|
+
return groupValue[1];
|
|
706
|
+
}
|
|
707
|
+
}
|
|
708
|
+
return (this.$data.group?.guid ?? null) as string | null;
|
|
709
|
+
}
|
|
710
|
+
public $getAcReadIds() {
|
|
711
|
+
return (this.$data.acRead?.map((entity: EntityInterface) => entity.guid) ??
|
|
712
|
+
null) as (string | null)[] | null;
|
|
713
|
+
}
|
|
714
|
+
public $getAcWriteIds() {
|
|
715
|
+
return (this.$data.acWrite?.map((entity: EntityInterface) => entity.guid) ??
|
|
716
|
+
null) as (string | null)[] | null;
|
|
717
|
+
}
|
|
718
|
+
public $getAcFullIds() {
|
|
719
|
+
return (this.$data.acFull?.map((entity: EntityInterface) => entity.guid) ??
|
|
720
|
+
null) as (string | null)[] | null;
|
|
563
721
|
}
|
|
564
722
|
|
|
565
723
|
public $getValidatable() {
|
|
566
|
-
this.$
|
|
724
|
+
this.$check();
|
|
567
725
|
|
|
568
726
|
// Access all the serialized properties to initialize them.
|
|
569
727
|
for (const key in this.$sdata) {
|
|
@@ -579,13 +737,13 @@ export default class Entity<T extends EntityData = EntityData>
|
|
|
579
737
|
}
|
|
580
738
|
|
|
581
739
|
public $getTags() {
|
|
582
|
-
this.$
|
|
740
|
+
this.$check();
|
|
583
741
|
|
|
584
742
|
return this.tags;
|
|
585
743
|
}
|
|
586
744
|
|
|
587
745
|
public $hasTag(...tags: string[]) {
|
|
588
|
-
this.$
|
|
746
|
+
this.$check();
|
|
589
747
|
|
|
590
748
|
if (!tags.length) {
|
|
591
749
|
return false;
|
|
@@ -611,10 +769,15 @@ export default class Entity<T extends EntityData = EntityData>
|
|
|
611
769
|
return this.guid === object.guid;
|
|
612
770
|
}
|
|
613
771
|
|
|
614
|
-
this.$
|
|
772
|
+
this.$check();
|
|
615
773
|
if (typeof object.$getData !== 'function') {
|
|
616
774
|
return false;
|
|
617
775
|
} else {
|
|
776
|
+
const obTags = [...object.tags].sort();
|
|
777
|
+
const myTags = [...this.tags].sort();
|
|
778
|
+
if (!isEqual(obTags, myTags)) {
|
|
779
|
+
return false;
|
|
780
|
+
}
|
|
618
781
|
const obData = object.$getData(true);
|
|
619
782
|
const myData = this.$getData(true);
|
|
620
783
|
return isEqual(obData, myData);
|
|
@@ -622,12 +785,11 @@ export default class Entity<T extends EntityData = EntityData>
|
|
|
622
785
|
}
|
|
623
786
|
|
|
624
787
|
public $jsonAcceptData(input: EntityJson, allowConflict = false) {
|
|
625
|
-
|
|
626
|
-
this.$referenceWake();
|
|
788
|
+
this.$check();
|
|
627
789
|
|
|
628
790
|
if (this.guid != input.guid) {
|
|
629
791
|
throw new EntityConflictError(
|
|
630
|
-
'Tried to accept JSON input for the wrong entity.'
|
|
792
|
+
'Tried to accept JSON input for the wrong entity.',
|
|
631
793
|
);
|
|
632
794
|
}
|
|
633
795
|
|
|
@@ -665,12 +827,27 @@ export default class Entity<T extends EntityData = EntityData>
|
|
|
665
827
|
|
|
666
828
|
const protectedData: EntityData = {};
|
|
667
829
|
const protectedProps = [...this.$protectedData];
|
|
668
|
-
if (
|
|
669
|
-
|
|
670
|
-
|
|
671
|
-
|
|
672
|
-
protectedProps.push('
|
|
673
|
-
protectedProps.push('
|
|
830
|
+
if (this.$nymph.tilmeld) {
|
|
831
|
+
protectedProps.push('acUser');
|
|
832
|
+
protectedProps.push('acGroup');
|
|
833
|
+
protectedProps.push('acOther');
|
|
834
|
+
protectedProps.push('acRead');
|
|
835
|
+
protectedProps.push('acWrite');
|
|
836
|
+
protectedProps.push('acFull');
|
|
837
|
+
if (
|
|
838
|
+
((this.constructor as EntityConstructor).class !== 'User' &&
|
|
839
|
+
(this.constructor as EntityConstructor).class !== 'Group') ||
|
|
840
|
+
!(this.$nymph.tilmeld as any).currentUser ||
|
|
841
|
+
(!(this.$nymph.tilmeld as any).currentUser.abilities?.includes(
|
|
842
|
+
'tilmeld/admin',
|
|
843
|
+
) &&
|
|
844
|
+
!(this.$nymph.tilmeld as any).currentUser.abilities?.includes(
|
|
845
|
+
'system/admin',
|
|
846
|
+
))
|
|
847
|
+
) {
|
|
848
|
+
protectedProps.push('user');
|
|
849
|
+
protectedProps.push('group');
|
|
850
|
+
}
|
|
674
851
|
}
|
|
675
852
|
for (const name of protectedProps) {
|
|
676
853
|
if (name in this.$data) {
|
|
@@ -703,11 +880,11 @@ export default class Entity<T extends EntityData = EntityData>
|
|
|
703
880
|
}
|
|
704
881
|
|
|
705
882
|
public $jsonAcceptPatch(patch: EntityPatch, allowConflict = false) {
|
|
706
|
-
this.$
|
|
883
|
+
this.$check();
|
|
707
884
|
|
|
708
885
|
if (this.guid != patch.guid) {
|
|
709
886
|
throw new EntityConflictError(
|
|
710
|
-
'Tried to accept JSON patch for the wrong entity.'
|
|
887
|
+
'Tried to accept JSON patch for the wrong entity.',
|
|
711
888
|
);
|
|
712
889
|
}
|
|
713
890
|
|
|
@@ -719,11 +896,35 @@ export default class Entity<T extends EntityData = EntityData>
|
|
|
719
896
|
}
|
|
720
897
|
this.mdate = patch.mdate;
|
|
721
898
|
|
|
899
|
+
const protectedProps = [...this.$protectedData];
|
|
900
|
+
if (this.$nymph.tilmeld) {
|
|
901
|
+
protectedProps.push('acUser');
|
|
902
|
+
protectedProps.push('acGroup');
|
|
903
|
+
protectedProps.push('acOther');
|
|
904
|
+
protectedProps.push('acRead');
|
|
905
|
+
protectedProps.push('acWrite');
|
|
906
|
+
protectedProps.push('acFull');
|
|
907
|
+
if (
|
|
908
|
+
((this.constructor as EntityConstructor).class !== 'User' &&
|
|
909
|
+
(this.constructor as EntityConstructor).class !== 'Group') ||
|
|
910
|
+
!(this.$nymph.tilmeld as any).currentUser ||
|
|
911
|
+
(!(this.$nymph.tilmeld as any).currentUser.abilities?.includes(
|
|
912
|
+
'tilmeld/admin',
|
|
913
|
+
) &&
|
|
914
|
+
!(this.$nymph.tilmeld as any).currentUser.abilities?.includes(
|
|
915
|
+
'system/admin',
|
|
916
|
+
))
|
|
917
|
+
) {
|
|
918
|
+
protectedProps.push('user');
|
|
919
|
+
protectedProps.push('group');
|
|
920
|
+
}
|
|
921
|
+
}
|
|
922
|
+
|
|
722
923
|
for (const name in patch.set) {
|
|
723
924
|
if (
|
|
724
925
|
(this.$allowlistData != null &&
|
|
725
926
|
this.$allowlistData.indexOf(name) === -1) ||
|
|
726
|
-
|
|
927
|
+
protectedProps.indexOf(name) !== -1 ||
|
|
727
928
|
this.$privateData.indexOf(name) !== -1
|
|
728
929
|
) {
|
|
729
930
|
continue;
|
|
@@ -731,7 +932,7 @@ export default class Entity<T extends EntityData = EntityData>
|
|
|
731
932
|
(this.$data as any)[name] = referencesToEntities(
|
|
732
933
|
patch.set[name],
|
|
733
934
|
this.$nymph,
|
|
734
|
-
this.$skipAc
|
|
935
|
+
this.$skipAc,
|
|
735
936
|
);
|
|
736
937
|
}
|
|
737
938
|
|
|
@@ -739,7 +940,7 @@ export default class Entity<T extends EntityData = EntityData>
|
|
|
739
940
|
if (
|
|
740
941
|
(this.$allowlistData != null &&
|
|
741
942
|
this.$allowlistData.indexOf(name) === -1) ||
|
|
742
|
-
|
|
943
|
+
protectedProps.indexOf(name) !== -1 ||
|
|
743
944
|
this.$privateData.indexOf(name) !== -1
|
|
744
945
|
) {
|
|
745
946
|
continue;
|
|
@@ -771,7 +972,7 @@ export default class Entity<T extends EntityData = EntityData>
|
|
|
771
972
|
}
|
|
772
973
|
|
|
773
974
|
public $putData(data: EntityData, sdata?: SerializedEntityData) {
|
|
774
|
-
this.$
|
|
975
|
+
this.$check();
|
|
775
976
|
|
|
776
977
|
const mySdata = sdata ?? this.$getSData();
|
|
777
978
|
for (const name in data) {
|
|
@@ -784,13 +985,13 @@ export default class Entity<T extends EntityData = EntityData>
|
|
|
784
985
|
(this.$dataStore as any)[name] = referencesToEntities(
|
|
785
986
|
data[name],
|
|
786
987
|
this.$nymph,
|
|
787
|
-
this.$skipAc
|
|
988
|
+
this.$skipAc,
|
|
788
989
|
);
|
|
789
990
|
}
|
|
790
991
|
this.$sdata = mySdata;
|
|
791
992
|
// Set original AC values if not set..
|
|
792
993
|
if (this.$originalAcValues == null) {
|
|
793
|
-
this.$originalAcValues = this.$
|
|
994
|
+
this.$originalAcValues = this.$getCurrentAcValues();
|
|
794
995
|
}
|
|
795
996
|
}
|
|
796
997
|
|
|
@@ -807,14 +1008,14 @@ export default class Entity<T extends EntityData = EntityData>
|
|
|
807
1008
|
) {
|
|
808
1009
|
throw new InvalidParametersError(
|
|
809
1010
|
'referenceSleep expects parameter 1 to be a valid Nymph entity ' +
|
|
810
|
-
'reference.'
|
|
1011
|
+
'reference.',
|
|
811
1012
|
);
|
|
812
1013
|
}
|
|
813
1014
|
const thisClass: string = (this.constructor as any).class;
|
|
814
1015
|
if (reference[2] !== thisClass) {
|
|
815
1016
|
throw new InvalidParametersError(
|
|
816
1017
|
'referenceSleep can only be called with an entity reference of the ' +
|
|
817
|
-
`same class. Given class: ${reference[2]}; this class: ${thisClass}
|
|
1018
|
+
`same class. Given class: ${reference[2]}; this class: ${thisClass}.`,
|
|
818
1019
|
);
|
|
819
1020
|
}
|
|
820
1021
|
this.$isASleepingReference = true;
|
|
@@ -822,49 +1023,137 @@ export default class Entity<T extends EntityData = EntityData>
|
|
|
822
1023
|
this.$sleepingReference = reference;
|
|
823
1024
|
}
|
|
824
1025
|
|
|
1026
|
+
/**
|
|
1027
|
+
* Check if this is a sleeping reference and throw an error if so.
|
|
1028
|
+
*/
|
|
1029
|
+
protected $check() {
|
|
1030
|
+
if (this.$isASleepingReference || this.$sleepingReference != null) {
|
|
1031
|
+
throw new EntityIsSleepingReferenceError(
|
|
1032
|
+
'This entity is in a sleeping reference state. You must use .$wake() to wake it.',
|
|
1033
|
+
);
|
|
1034
|
+
}
|
|
1035
|
+
}
|
|
1036
|
+
|
|
1037
|
+
/**
|
|
1038
|
+
* Check if this is a sleeping reference.
|
|
1039
|
+
*/
|
|
1040
|
+
public $asleep() {
|
|
1041
|
+
return this.$isASleepingReference || this.$sleepingReference != null;
|
|
1042
|
+
}
|
|
1043
|
+
|
|
825
1044
|
/**
|
|
826
1045
|
* Wake from a sleeping reference.
|
|
827
|
-
*
|
|
828
|
-
* @returns True on success, false on failure.
|
|
829
1046
|
*/
|
|
830
|
-
|
|
1047
|
+
public $wake() {
|
|
831
1048
|
if (!this.$isASleepingReference || this.$sleepingReference == null) {
|
|
832
|
-
|
|
1049
|
+
this.$wakePromise = null;
|
|
1050
|
+
return Promise.resolve(this);
|
|
833
1051
|
}
|
|
834
|
-
|
|
835
|
-
|
|
836
|
-
|
|
837
|
-
|
|
838
|
-
skipAc: this.$skipAc,
|
|
839
|
-
},
|
|
840
|
-
{ type: '&', guid: this.$sleepingReference[1] }
|
|
841
|
-
);
|
|
842
|
-
if (entity == null) {
|
|
843
|
-
return false;
|
|
1052
|
+
if (this.$sleepingReference?.[1] == null) {
|
|
1053
|
+
throw new InvalidStateError(
|
|
1054
|
+
'Tried to wake a sleeping reference with no GUID.',
|
|
1055
|
+
);
|
|
844
1056
|
}
|
|
845
|
-
this.$
|
|
846
|
-
|
|
847
|
-
|
|
848
|
-
|
|
849
|
-
|
|
850
|
-
|
|
851
|
-
|
|
852
|
-
|
|
1057
|
+
if (!this.$wakePromise) {
|
|
1058
|
+
const EntityClass = this.$nymph.getEntityClass(
|
|
1059
|
+
this.$sleepingReference[2],
|
|
1060
|
+
);
|
|
1061
|
+
this.$wakePromise = this.$nymph
|
|
1062
|
+
.getEntity(
|
|
1063
|
+
{
|
|
1064
|
+
class: EntityClass,
|
|
1065
|
+
skipAc: this.$skipAc,
|
|
1066
|
+
},
|
|
1067
|
+
{ type: '&', guid: this.$sleepingReference[1] },
|
|
1068
|
+
)
|
|
1069
|
+
.then((entity) => {
|
|
1070
|
+
if (entity == null || entity.guid == null) {
|
|
1071
|
+
return Promise.reject(
|
|
1072
|
+
new InvalidStateError(
|
|
1073
|
+
'The sleeping reference could not be retrieved.',
|
|
1074
|
+
),
|
|
1075
|
+
);
|
|
1076
|
+
}
|
|
1077
|
+
this.$isASleepingReference = false;
|
|
1078
|
+
this.$sleepingReference = null;
|
|
1079
|
+
this.guid = entity.guid;
|
|
1080
|
+
this.tags = entity.tags;
|
|
1081
|
+
this.cdate = entity.cdate;
|
|
1082
|
+
this.mdate = entity.mdate;
|
|
1083
|
+
this.$putData(entity.$getData(), entity.$getSData());
|
|
1084
|
+
|
|
1085
|
+
return this;
|
|
1086
|
+
})
|
|
1087
|
+
.finally(() => {
|
|
1088
|
+
this.$wakePromise = null;
|
|
1089
|
+
});
|
|
1090
|
+
}
|
|
1091
|
+
return this.$wakePromise;
|
|
1092
|
+
}
|
|
1093
|
+
|
|
1094
|
+
public $wakeAll(level?: number) {
|
|
1095
|
+
return new Promise((resolve, reject) => {
|
|
1096
|
+
// Run this once this entity is wake.
|
|
1097
|
+
const wakeProps = () => {
|
|
1098
|
+
let newLevel;
|
|
1099
|
+
// If level is undefined, keep going forever, otherwise, stop once we've
|
|
1100
|
+
// gone deep enough.
|
|
1101
|
+
if (level !== undefined) {
|
|
1102
|
+
newLevel = level - 1;
|
|
1103
|
+
}
|
|
1104
|
+
if (newLevel !== undefined && newLevel < 0) {
|
|
1105
|
+
resolve(this);
|
|
1106
|
+
return;
|
|
1107
|
+
}
|
|
1108
|
+
const promises = [];
|
|
1109
|
+
// Go through data looking for entities to wake.
|
|
1110
|
+
for (let [key, value] of Object.entries(this.$data)) {
|
|
1111
|
+
if (value instanceof Entity && value.$isASleepingReference) {
|
|
1112
|
+
promises.push(value.$wakeAll(newLevel));
|
|
1113
|
+
} else if (Array.isArray(value)) {
|
|
1114
|
+
for (let i = 0; i < value.length; i++) {
|
|
1115
|
+
if (
|
|
1116
|
+
value[i] instanceof Entity &&
|
|
1117
|
+
value[i].$isASleepingReference
|
|
1118
|
+
) {
|
|
1119
|
+
promises.push(value[i].$wakeAll(newLevel));
|
|
1120
|
+
}
|
|
1121
|
+
}
|
|
1122
|
+
}
|
|
1123
|
+
}
|
|
1124
|
+
if (promises.length) {
|
|
1125
|
+
Promise.all(promises).then(
|
|
1126
|
+
() => resolve(this),
|
|
1127
|
+
(errObj) => reject(errObj),
|
|
1128
|
+
);
|
|
1129
|
+
} else {
|
|
1130
|
+
resolve(this);
|
|
1131
|
+
}
|
|
1132
|
+
};
|
|
1133
|
+
|
|
1134
|
+
if (this.$isASleepingReference) {
|
|
1135
|
+
this.$wake().then(wakeProps, (errObj) => reject(errObj));
|
|
1136
|
+
} else {
|
|
1137
|
+
wakeProps();
|
|
1138
|
+
}
|
|
1139
|
+
}) as Promise<Entity<T>>;
|
|
853
1140
|
}
|
|
854
1141
|
|
|
855
1142
|
public async $refresh() {
|
|
856
|
-
this.$
|
|
1143
|
+
await this.$wake();
|
|
857
1144
|
|
|
858
1145
|
if (this.guid == null) {
|
|
859
1146
|
return false;
|
|
860
1147
|
}
|
|
861
1148
|
const refresh = await this.$nymph.getEntity(
|
|
862
1149
|
{
|
|
863
|
-
class: this.
|
|
1150
|
+
class: this.$nymph.getEntityClass(
|
|
1151
|
+
this.constructor as EntityConstructor,
|
|
1152
|
+
),
|
|
864
1153
|
skipCache: true,
|
|
865
1154
|
skipAc: this.$skipAc,
|
|
866
1155
|
},
|
|
867
|
-
{ type: '&', guid: this.guid }
|
|
1156
|
+
{ type: '&', guid: this.guid },
|
|
868
1157
|
);
|
|
869
1158
|
if (refresh == null) {
|
|
870
1159
|
return 0;
|
|
@@ -877,13 +1166,13 @@ export default class Entity<T extends EntityData = EntityData>
|
|
|
877
1166
|
}
|
|
878
1167
|
|
|
879
1168
|
public $removeTag(...tags: string[]) {
|
|
880
|
-
this.$
|
|
1169
|
+
this.$check();
|
|
881
1170
|
|
|
882
1171
|
this.tags = difference(this.tags, tags);
|
|
883
1172
|
}
|
|
884
1173
|
|
|
885
1174
|
public async $save(): Promise<boolean> {
|
|
886
|
-
this.$
|
|
1175
|
+
await this.$wake();
|
|
887
1176
|
|
|
888
1177
|
return await this.$nymph.saveEntity(this);
|
|
889
1178
|
}
|