@koalarx/nest 3.1.35 → 3.1.37

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.
@@ -13,9 +13,15 @@ export type EntityProps<T extends IComparable<T>> = Overwrite<Omit<{
13
13
  } ? U : never;
14
14
  }>;
15
15
  export declare abstract class EntityBase<T extends IComparable<T>> implements IComparable<T> {
16
+ private _trackHasUpdateOnSet;
17
+ private _setTrackingProxy?;
16
18
  _id: IComparableId;
17
19
  _action: EntityActionType;
20
+ _hasUpdate: boolean;
18
21
  constructor(props?: EntityProps<T>);
22
+ protected startHasUpdateTracking(): void;
23
+ protected stopHasUpdateTracking(): void;
24
+ protected createSetTrackingProxy(): this;
19
25
  automap(props?: EntityProps<T>, context?: AutomapContext): void;
20
26
  equals(obj: EntityBase<T>): boolean;
21
27
  }
@@ -11,13 +11,75 @@ var EntityActionType;
11
11
  EntityActionType[EntityActionType["update"] = 2] = "update";
12
12
  })(EntityActionType || (exports.EntityActionType = EntityActionType = {}));
13
13
  class EntityBase {
14
+ _trackHasUpdateOnSet = false;
15
+ _setTrackingProxy;
14
16
  _id;
15
17
  _action = EntityActionType.create;
18
+ _hasUpdate = false;
16
19
  constructor(props) {
20
+ Object.defineProperties(this, {
21
+ _trackHasUpdateOnSet: {
22
+ enumerable: false,
23
+ configurable: true,
24
+ writable: true,
25
+ value: false,
26
+ },
27
+ _setTrackingProxy: {
28
+ enumerable: false,
29
+ configurable: true,
30
+ writable: true,
31
+ value: undefined,
32
+ },
33
+ _id: {
34
+ enumerable: false,
35
+ configurable: true,
36
+ writable: true,
37
+ value: this._id,
38
+ },
39
+ _action: {
40
+ enumerable: false,
41
+ configurable: true,
42
+ writable: true,
43
+ value: this._action,
44
+ },
45
+ _hasUpdate: {
46
+ enumerable: false,
47
+ configurable: true,
48
+ writable: true,
49
+ value: this._hasUpdate,
50
+ },
51
+ });
17
52
  if (props) {
18
53
  this.automap(props);
19
54
  }
20
55
  }
56
+ startHasUpdateTracking() {
57
+ this._trackHasUpdateOnSet = true;
58
+ }
59
+ stopHasUpdateTracking() {
60
+ this._trackHasUpdateOnSet = false;
61
+ }
62
+ createSetTrackingProxy() {
63
+ if (this._setTrackingProxy) {
64
+ return this._setTrackingProxy;
65
+ }
66
+ this._setTrackingProxy = new Proxy(this, {
67
+ set: (target, property, value, receiver) => {
68
+ const success = Reflect.set(target, property, value, receiver);
69
+ if (success &&
70
+ target._trackHasUpdateOnSet &&
71
+ property !== '_hasUpdate' &&
72
+ property !== '_action' &&
73
+ property !== '_id' &&
74
+ property !== '_trackHasUpdateOnSet' &&
75
+ property !== '_setTrackingProxy') {
76
+ target._hasUpdate = true;
77
+ }
78
+ return success;
79
+ },
80
+ });
81
+ return this._setTrackingProxy;
82
+ }
21
83
  automap(props, context = (0, automap_cycle_context_1.createAutomapContext)()) {
22
84
  if (props) {
23
85
  if (typeof props === 'object' && props !== null) {
@@ -8,12 +8,5 @@ export interface IdConfig<T extends EntityProps<any>> {
8
8
  composite?: readonly (keyof T)[];
9
9
  custom?: (props: T) => string | number | CompositeId;
10
10
  }
11
- export declare function Entity<T extends new (...args: any[]) => EntityBase<any>>(id?: keyof EntityProps<InstanceType<T>> | IdConfig<EntityProps<InstanceType<T>>>): (target: T) => {
12
- new (...args: any[]): {
13
- _id: import("../utils/interfaces/icomparable").IComparableId;
14
- _action: import("./entity.base").EntityActionType;
15
- automap(props?: import("./entity.base").EntityProps<any> | undefined, context?: import("../utils/automap-cycle-context").AutomapContext): void;
16
- equals(obj: EntityBase<any>): boolean;
17
- };
18
- } & T;
11
+ export declare function Entity(id?: keyof EntityProps<any> | IdConfig<EntityProps<any>>): <T extends new (...args: any[]) => EntityBase<any>>(target: T) => T;
19
12
  export {};
@@ -14,9 +14,12 @@ function Entity(id) {
14
14
  class NewConstructor extends target {
15
15
  constructor(...args) {
16
16
  super(...args);
17
+ this.stopHasUpdateTracking();
17
18
  if (typeof this.automap === 'function') {
18
19
  this.automap(args[0]);
19
20
  }
21
+ this.startHasUpdateTracking();
22
+ return this.createSetTrackingProxy();
20
23
  }
21
24
  }
22
25
  Object.setPrototypeOf(NewConstructor.prototype, target.prototype);
@@ -27,6 +30,8 @@ function Entity(id) {
27
30
  });
28
31
  const idConfig = normalizeIdConfig(id);
29
32
  Reflect.defineMetadata('entity:id', idConfig, NewConstructor.prototype);
33
+ Reflect.defineMetadata('entity:decorated-constructor', NewConstructor, target.prototype);
34
+ Reflect.defineMetadata('entity:decorated-constructor', NewConstructor, NewConstructor.prototype);
30
35
  return NewConstructor;
31
36
  };
32
37
  }
@@ -210,7 +210,8 @@ class RepositoryBase {
210
210
  else if (entity[key] instanceof entity_base_1.EntityBase) {
211
211
  const entityInstance = entity[key];
212
212
  const modelName = entity[key].constructor.name;
213
- if (entity[key]._action === entity_base_1.EntityActionType.update) {
213
+ if (entity[key]._action === entity_base_1.EntityActionType.update &&
214
+ entity[key]._hasUpdate) {
214
215
  relationUpdates.push({
215
216
  modelName: (0, KlString_1.toCamelCase)(modelName),
216
217
  entityInstance,
@@ -284,8 +285,15 @@ class RepositoryBase {
284
285
  }
285
286
  createEntity(data, entityClass) {
286
287
  const entity = new (entityClass || this._modelName)();
288
+ const trackedEntity = entity;
289
+ if (typeof trackedEntity.stopHasUpdateTracking === 'function') {
290
+ trackedEntity.stopHasUpdateTracking();
291
+ }
287
292
  entity._action = entity_base_1.EntityActionType.update;
288
293
  entity.automap(data);
294
+ if (typeof trackedEntity.startHasUpdateTracking === 'function') {
295
+ trackedEntity.startHasUpdateTracking();
296
+ }
289
297
  return entity;
290
298
  }
291
299
  orphanRemoval(client, entity) {
@@ -377,7 +385,16 @@ class RepositoryBase {
377
385
  }
378
386
  if (relationUpdates.length > 0) {
379
387
  await Promise.all([
380
- ...relationUpdates.map((relation) => transaction[relation.modelName].update(relation.schema)),
388
+ ...relationUpdates.map((relationUpdate) => transaction[relationUpdate.modelName]
389
+ .update(relationUpdate.schema)
390
+ .then(() => {
391
+ if (relationUpdate.relations.length === 0) {
392
+ return Promise.all([]);
393
+ }
394
+ return Promise.all(relationUpdate.relations.map((relation) => {
395
+ return this.persistRelations(transaction, relation);
396
+ }));
397
+ })),
381
398
  ]);
382
399
  }
383
400
  if (relationCreates.length > 0) {
@@ -15,12 +15,19 @@ function mapEntityReference(value, EntityOnPropKey, context, action) {
15
15
  if (cachedEntity) {
16
16
  return cachedEntity;
17
17
  }
18
- const entity = new EntityOnPropKey();
18
+ const DecoratedEntityConstructor = Reflect.getMetadata('entity:decorated-constructor', EntityOnPropKey.prototype) ?? EntityOnPropKey;
19
+ const entity = new DecoratedEntityConstructor();
20
+ const trackedEntity = entity;
19
21
  if (entity && typeof entity.automap === 'function') {
20
- ;
21
- entity._action = action;
22
+ if (typeof trackedEntity.stopHasUpdateTracking === 'function') {
23
+ trackedEntity.stopHasUpdateTracking();
24
+ }
25
+ trackedEntity._action = action;
22
26
  context.references.set(value, entity);
23
- entity.automap(value, context);
27
+ trackedEntity.automap(value, context);
28
+ if (typeof trackedEntity.startHasUpdateTracking === 'function') {
29
+ trackedEntity.startHasUpdateTracking();
30
+ }
24
31
  }
25
32
  return entity;
26
33
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@koalarx/nest",
3
- "version": "3.1.35",
3
+ "version": "3.1.37",
4
4
  "description": "",
5
5
  "author": "Igor D. Rangel",
6
6
  "license": "MIT",