@entity-access/entity-access 1.2.4 → 1.2.6

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.
@@ -1,5 +1,5 @@
1
1
  import EntityAccessError from "../../common/EntityAccessError.js";
2
- import { IColumn } from "../../decorators/IColumn.js";
2
+ import { IColumn, IEntityRelation } from "../../decorators/IColumn.js";
3
3
  import NameParser from "../../decorators/parser/NameParser.js";
4
4
  import EntityType from "../../entity-query/EntityType.js";
5
5
  import DateTime from "../../types/DateTime.js";
@@ -47,6 +47,7 @@ export default class ChangeEntry<T = any> implements IChanges {
47
47
  ce.pending = [];
48
48
  ce.dependents = new Set();
49
49
  ce.modified = new Map();
50
+ ce.order = 1;
50
51
  return ce;
51
52
  }
52
53
 
@@ -240,7 +241,7 @@ export default class ChangeEntry<T = any> implements IChanges {
240
241
  if (dbValues !== void 0) {
241
242
  const { entity, type } = this;
242
243
  for (const key in dbValues) {
243
- if (Object.prototype.hasOwnProperty.call(dbValues, key)) {
244
+ if (Object.hasOwn(dbValues, key)) {
244
245
  const element = dbValues[key];
245
246
  entity[key] = element;
246
247
  }
@@ -285,7 +286,7 @@ export default class ChangeEntry<T = any> implements IChanges {
285
286
  const { entity, original } = this;
286
287
  if (original) {
287
288
  for (const key in original) {
288
- if (Object.prototype.hasOwnProperty.call(original, key)) {
289
+ if (Object.hasOwn(original, key)) {
289
290
  const element = original[key];
290
291
  entity[key] = element;
291
292
  }
@@ -296,12 +297,9 @@ export default class ChangeEntry<T = any> implements IChanges {
296
297
  }
297
298
 
298
299
  detectDependencies() {
299
- const { type: { relations }, entity } = this;
300
- // for parent relations.. check if related key is set or not...
301
- for (const iterator of relations) {
302
- if (iterator.isInverseRelation) {
303
- continue;
304
- }
300
+ const { type: { fkRelations }, entity } = this;
301
+
302
+ for (const iterator of fkRelations) {
305
303
 
306
304
  // get related entry..
307
305
  const related = entity[iterator.name];
@@ -309,82 +307,108 @@ export default class ChangeEntry<T = any> implements IChanges {
309
307
  continue;
310
308
  }
311
309
 
312
- // if related has key defined.. set it...
313
- // const rKey = iterator.relatedEntity.keys[0];
314
-
315
- // lets set the prototype...
310
+ /**
311
+ * We need to set prototype,
312
+ *
313
+ * Reason:
314
+ * The prototype is not set when object is parsed from
315
+ * JSON and changeSet requires type
316
+ */
316
317
  const prototype = iterator.relatedTypeClass.prototype;
317
318
  if (Object.getPrototypeOf(related) !== prototype) {
318
319
  Object.setPrototypeOf(related, prototype);
319
320
  }
320
- const relatedChanges = this.changeSet.getEntry(related);
321
-
322
- for (const { fkColumn, relatedKeyColumn } of iterator.fkMap) {
323
- const keyValue = related[relatedKeyColumn.name];
324
- if (keyValue === void 0 || keyValue === null) {
325
-
326
- if(relatedChanges.dependents.has(this)) {
327
- continue;
328
- }
329
- relatedChanges.dependents.add(this);
330
321
 
331
- this.order++;
322
+ const relatedChanges = this.changeSet.getEntry(related);
323
+ this.order += relatedChanges.order + 1;
332
324
 
333
- for (const d of this.dependents) {
334
- d.order += this.order + 1;
335
- }
325
+ relatedChanges.detectDependencies();
336
326
 
337
- if (!fkColumn.columnName) {
338
- throw new EntityAccessError(`Configuration error, fk not set for ${fkColumn.name}`);
339
- }
327
+ for (const { fkColumn, relatedKeyColumn } of iterator.fkMap) {
328
+ const key = related[relatedKeyColumn.name];
329
+ if (key === void 0 || key === null) {
340
330
  relatedChanges.pending.push(() => {
341
- this.entity[fkColumn.name] = related[relatedKeyColumn.name];
331
+ this.setValue(fkColumn, related[relatedKeyColumn.name]);
342
332
  });
343
- if (this.status !== "inserted") {
344
- this.modified.set(iterator, { column: fkColumn, oldValue: void 0, newValue: void 0});
345
- }
346
- }
347
- continue;
348
- }
349
-
350
- if(!relatedChanges.dependents.has(this)) {
351
- relatedChanges.dependents.add(this);
352
- this.order += relatedChanges.order + 1;
353
- for (const d of this.dependents) {
354
- d.order += this.order + 1;
333
+ } else {
334
+ this.setValue(fkColumn, key);
355
335
  }
356
336
  }
357
- for (const { fkColumn, relatedKeyColumn } of iterator.fkMap) {
358
- this.entity[fkColumn.name] = related[relatedKeyColumn.name];
359
- }
360
- // this.entity[iterator.fkColumn.name] = related[rKey.name];
361
337
  }
338
+
339
+ this.setupInverseProperties();
362
340
  }
363
341
 
364
342
  setupInverseProperties() {
365
343
  const deleted = this.status === "deleted";
366
- for (const iterator of this.type.relations) {
367
- if (!iterator.isInverseRelation) {
368
- continue;
369
- }
344
+ for (const iterator of this.type.inverseRelations) {
370
345
  const { relatedName } = iterator;
371
346
  const related = this.entity[iterator.name];
372
347
  if (related === void 0) {
373
348
  continue;
374
349
  }
375
350
  if (Array.isArray(related)) {
351
+ if (deleted) {
352
+ this.pending.push(() => {
353
+ const index = related.indexOf(this.entity);
354
+ if (index !== -1) {
355
+ related.splice(index, 1);
356
+ }
357
+ });
358
+ continue;
359
+ }
360
+
376
361
  for (const r of related) {
377
- const existing = r[iterator.relatedName];
378
- if (existing !== this.entity) {
379
- r[iterator.relatedName] = this.entity;
380
- }
362
+ this.setInversePropertyValue(r, iterator);
381
363
  }
382
364
  continue;
383
365
  }
384
- related[relatedName] = this.entity;
385
366
  if (deleted) {
386
367
  this.pending.push(() => delete related[relatedName]);
368
+ continue;
369
+ }
370
+ this.setInversePropertyValue(related, iterator);
371
+ }
372
+ }
373
+
374
+
375
+ private setInversePropertyValue(related: any, { relatedName , relatedRelation }: IEntityRelation) {
376
+ const { entity } = this;
377
+ const re = this.changeSet.getEntry(related);
378
+ re.order += this.order + 1;
379
+ if (related[relatedName] !== entity) {
380
+ related[relatedName] = entity;
381
+ }
382
+ if (this.status !== "inserted") {
383
+ for (const { fkColumn , relatedKeyColumn } of relatedRelation.fkMap) {
384
+ re.setValue(fkColumn, entity[relatedKeyColumn.name]);
387
385
  }
386
+ return;
388
387
  }
388
+ this.pending.push(() => {
389
+ for (const { fkColumn , relatedKeyColumn } of relatedRelation.fkMap) {
390
+ re.setValue(fkColumn, entity[relatedKeyColumn.name]);
391
+ }
392
+ });
389
393
  }
394
+
395
+ private setValue(column: IColumn, newValue) {
396
+ const oldValue = this.entity[column.name];
397
+ if (oldValue === newValue) {
398
+ return;
399
+ }
400
+ this.entity[column.name] = newValue;
401
+ this.modified.set(column, {
402
+ column,
403
+ newValue,
404
+ oldValue,
405
+ });
406
+ switch(this.status) {
407
+ case "detached":
408
+ case "unchanged":
409
+ this.status = "modified";
410
+ break;
411
+ }
412
+ }
413
+
390
414
  }
@@ -37,23 +37,15 @@ export default class ChangeSet {
37
37
 
38
38
  *getChanges(max = 5): Generator<ChangeEntry, any, any> {
39
39
 
40
- this.detectChanges();
40
+ const initialChanges = this.detectChanges();
41
41
 
42
- // const pending = [] as ChangeEntry[];
43
- // using d = this.addedEvent.listen((ce) => pending.push(ce.detail));
42
+ let copy = this.pending = [] as ChangeEntry[];
44
43
 
45
-
46
- let copy = this.pending = [];
47
-
48
- yield * [].concat(this.entries) as any;
44
+ yield *initialChanges;
49
45
 
50
46
  while(copy.length) {
51
47
  const next = this.pending = [];
52
- for (const iterator of copy) {
53
- iterator.setupInverseProperties();
54
- iterator.detect();
55
- yield iterator;
56
- }
48
+ yield * this.detectChanges(copy);
57
49
  copy = next;
58
50
  }
59
51
 
@@ -125,17 +117,29 @@ export default class ChangeSet {
125
117
  /**
126
118
  * Detect changes will detect and sort the entries as they should be inserted.
127
119
  */
128
- public detectChanges() {
120
+ public detectChanges(source = this.entries) {
129
121
 
130
- for (const iterator of this.entries) {
122
+ const changes = [] as ChangeEntry[];
123
+
124
+ for (const iterator of source) {
131
125
  iterator.setupInverseProperties();
132
126
  }
133
127
 
134
- for (const iterator of this.entries) {
128
+ for (const iterator of source) {
135
129
  iterator.detect();
130
+ switch(iterator.status) {
131
+ case "detached":
132
+ case "unchanged":
133
+ continue;
134
+ default:
135
+ changes.push(iterator);
136
+ break;
137
+ }
136
138
  }
137
139
 
138
- this.entries.sort((a, b) => a.order - b.order);
140
+ // this.entries.sort((a, b) => a.order - b.order);
141
+ changes.sort((a, b) => a.order - b.order);
142
+ return changes;
139
143
 
140
144
  }
141
145