@entity-access/entity-access 1.2.5 → 1.2.9

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.
Files changed (44) hide show
  1. package/dist/.tsbuildinfo +1 -0
  2. package/dist/common/JsonGenerator.js +1 -1
  3. package/dist/common/JsonGenerator.js.map +1 -1
  4. package/dist/common/cloner.js +1 -1
  5. package/dist/common/cloner.js.map +1 -1
  6. package/dist/compiler/ISqlHelpers.js +2 -2
  7. package/dist/compiler/ISqlHelpers.js.map +1 -1
  8. package/dist/decorators/Column.js +1 -1
  9. package/dist/decorators/Column.js.map +1 -1
  10. package/dist/di/di.js +1 -1
  11. package/dist/di/di.js.map +1 -1
  12. package/dist/drivers/base/BaseDriver.js +3 -3
  13. package/dist/drivers/base/BaseDriver.js.map +1 -1
  14. package/dist/model/EntityContext.d.ts.map +1 -1
  15. package/dist/model/EntityContext.js +14 -15
  16. package/dist/model/EntityContext.js.map +1 -1
  17. package/dist/model/EntitySource.js +8 -8
  18. package/dist/model/EntitySource.js.map +1 -1
  19. package/dist/model/changes/ChangeEntry.d.ts +2 -0
  20. package/dist/model/changes/ChangeEntry.d.ts.map +1 -1
  21. package/dist/model/changes/ChangeEntry.js +64 -66
  22. package/dist/model/changes/ChangeEntry.js.map +1 -1
  23. package/dist/model/events/FilteredExpression.d.ts.map +1 -1
  24. package/dist/model/events/FilteredExpression.js +1 -2
  25. package/dist/model/events/FilteredExpression.js.map +1 -1
  26. package/dist/query/ast/Expressions.js +2 -2
  27. package/dist/query/ast/Expressions.js.map +1 -1
  28. package/dist/query/ast/ReplaceParameter.js +1 -1
  29. package/dist/query/ast/ReplaceParameter.js.map +1 -1
  30. package/package.json +3 -3
  31. package/src/common/JsonGenerator.ts +1 -1
  32. package/src/common/cloner.ts +1 -1
  33. package/src/compiler/ISqlHelpers.ts +2 -2
  34. package/src/decorators/Column.ts +1 -1
  35. package/src/di/di.ts +1 -1
  36. package/src/drivers/base/BaseDriver.ts +3 -3
  37. package/src/model/EntityContext.ts +15 -16
  38. package/src/model/EntitySource.ts +8 -8
  39. package/src/model/changes/ChangeEntry.ts +67 -74
  40. package/src/model/events/FilteredExpression.ts +1 -2
  41. package/src/query/ast/Expressions.ts +2 -2
  42. package/src/query/ast/ReplaceParameter.ts +1 -1
  43. package/tsconfig.json +1 -0
  44. package/tsconfig.tsbuildinfo +0 -1
package/src/di/di.ts CHANGED
@@ -163,7 +163,7 @@ export class ServiceProvider implements IDisposable {
163
163
  const keys = type.prototype[injectServiceKeysSymbol];
164
164
  if (keys) {
165
165
  for (const key in keys) {
166
- if (Object.prototype.hasOwnProperty.call(keys, key)) {
166
+ if (Object.hasOwn(keys, key)) {
167
167
  const element = keys[key];
168
168
  instance[key] ??= this.resolve(element);
169
169
  }
@@ -417,7 +417,7 @@ export abstract class BaseDriver {
417
417
  createSelectWithKeysExpression(type: EntityType, check: any, returnFields: Expression[] ) {
418
418
  let where = null as Expression;
419
419
  for (const key in check) {
420
- if (Object.prototype.hasOwnProperty.call(check, key)) {
420
+ if (Object.hasOwn(check, key)) {
421
421
  const element = check[key];
422
422
  const column = type.getField(key).quotedColumnNameExp;
423
423
  const condition = Expression.equal(column, Expression.constant(element));
@@ -448,7 +448,7 @@ export abstract class BaseDriver {
448
448
  if (mode === "delete") {
449
449
  let where = null as Expression;
450
450
  for (const key in test) {
451
- if (Object.prototype.hasOwnProperty.call(test, key)) {
451
+ if (Object.hasOwn(test, key)) {
452
452
  const element = test[key];
453
453
  const { quotedColumnNameExp } = type.getField(key);
454
454
  const compare = Expression.equal(quotedColumnNameExp, Expression.constant(element));
@@ -520,7 +520,7 @@ export abstract class BaseDriver {
520
520
 
521
521
  if(test) {
522
522
  for (const key in test) {
523
- if (Object.prototype.hasOwnProperty.call(test, key)) {
523
+ if (Object.hasOwn(test, key)) {
524
524
  const element = test[key];
525
525
  const { quotedColumnNameExp } = type.getField(key);
526
526
  keys.push(Expression.equal(quotedColumnNameExp, Expression.constant(element)));
@@ -195,7 +195,7 @@ export default class EntityContext {
195
195
  await events.beforeInsert(iterator.entity, iterator);
196
196
  verificationSession?.queueVerification(iterator, events);
197
197
  pending.push({ status: iterator.status, change: iterator, events });
198
- iterator.setupInverseProperties();
198
+ iterator.detectDependencies();
199
199
  copy.push(iterator);
200
200
  continue;
201
201
  case "modified":
@@ -216,23 +216,22 @@ export default class EntityContext {
216
216
 
217
217
  await verificationSession?.verifyAsync();
218
218
 
219
+ copy.sort((a, b) => a.order - b.order);
220
+
219
221
  await this.saveChangesInternalWithoutEvents(options, copy);
220
222
 
221
- if (pending.length > 0) {
222
-
223
- for (const { status, change, change: { entity}, events } of pending) {
224
- switch(status) {
225
- case "inserted":
226
- await events.afterInsert(entity, change);
227
- continue;
228
- case "modified":
229
- await events.afterUpdate(entity, change);
230
- change.clearUpdated();
231
- continue;
232
- case "deleted":
233
- await events.afterDelete(entity, change);
234
- continue;
235
- }
223
+ for (const { status, change, change: { entity}, events } of pending) {
224
+ switch(status) {
225
+ case "inserted":
226
+ await events.afterInsert(entity, change);
227
+ continue;
228
+ case "modified":
229
+ await events.afterUpdate(entity, change);
230
+ change.clearUpdated();
231
+ continue;
232
+ case "deleted":
233
+ await events.afterDelete(entity, change);
234
+ continue;
236
235
  }
237
236
  }
238
237
 
@@ -16,7 +16,7 @@ const removeUndefined = (obj) => {
16
16
  }
17
17
  const r = {};
18
18
  for (const key in obj) {
19
- if (Object.prototype.hasOwnProperty.call(obj, key)) {
19
+ if (Object.hasOwn(obj, key)) {
20
20
  const element = obj[key];
21
21
  if (element === void 0) {
22
22
  continue;
@@ -77,7 +77,7 @@ export class EntityStatements<T = any> {
77
77
  const result = r.rows[0];
78
78
  if (result) {
79
79
  for (const key in result) {
80
- if (Object.prototype.hasOwnProperty.call(result, key)) {
80
+ if (Object.hasOwn(result, key)) {
81
81
  const element = result[key];
82
82
  entity[key] = element;
83
83
  }
@@ -105,7 +105,7 @@ export class EntityStatements<T = any> {
105
105
  const result = r.rows[0];
106
106
  if (result) {
107
107
  for (const key in result) {
108
- if (Object.prototype.hasOwnProperty.call(result, key)) {
108
+ if (Object.hasOwn(result, key)) {
109
109
  const element = result[key];
110
110
  entity[key] = element;
111
111
  }
@@ -133,7 +133,7 @@ export class EntityStatements<T = any> {
133
133
  const result = r.rows[0];
134
134
  if (result) {
135
135
  for (const key in result) {
136
- if (Object.prototype.hasOwnProperty.call(result, key)) {
136
+ if (Object.hasOwn(result, key)) {
137
137
  const element = result[key];
138
138
  entity[key] = element;
139
139
  }
@@ -189,7 +189,7 @@ export class EntityStatements<T = any> {
189
189
  if (existing) {
190
190
  existing = updateAfterSelect(existing);
191
191
  for (const key in existing) {
192
- if (Object.prototype.hasOwnProperty.call(existing, key)) {
192
+ if (Object.hasOwn(existing as any, key)) {
193
193
  entity[key] = existing[key];
194
194
  }
195
195
  }
@@ -300,7 +300,7 @@ export class EntitySource<T = any> {
300
300
  if (er.rows?.[0]) {
301
301
  const fr = er.rows[0];
302
302
  for (const key in fr) {
303
- if (Object.prototype.hasOwnProperty.call(fr, key)) {
303
+ if (Object.hasOwn(fr, key)) {
304
304
  const element = fr[key];
305
305
  const name = this.model.getColumn(key).name;
306
306
  returnEntity[name] = element;
@@ -314,7 +314,7 @@ export class EntitySource<T = any> {
314
314
  const original = { ... returnEntity, ... changes };
315
315
  const updates = updateAfterSelect(original);
316
316
  for (const key in updates) {
317
- if (Object.prototype.hasOwnProperty.call(updates, key)) {
317
+ if (Object.hasOwn(updates as any, key)) {
318
318
  const element = updates[key];
319
319
  changes[key] = element;
320
320
  }
@@ -341,7 +341,7 @@ export class EntitySource<T = any> {
341
341
  if(r.rows?.length) {
342
342
  const first = r.rows[0];
343
343
  for (const key in first) {
344
- if (Object.prototype.hasOwnProperty.call(first, key)) {
344
+ if (Object.hasOwn(first, key)) {
345
345
  const element = first[key];
346
346
  const name = this.model.getColumn(key).name;
347
347
  returnEntity[name] ??= element;
@@ -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";
@@ -241,7 +241,7 @@ export default class ChangeEntry<T = any> implements IChanges {
241
241
  if (dbValues !== void 0) {
242
242
  const { entity, type } = this;
243
243
  for (const key in dbValues) {
244
- if (Object.prototype.hasOwnProperty.call(dbValues, key)) {
244
+ if (Object.hasOwn(dbValues, key)) {
245
245
  const element = dbValues[key];
246
246
  entity[key] = element;
247
247
  }
@@ -286,7 +286,7 @@ export default class ChangeEntry<T = any> implements IChanges {
286
286
  const { entity, original } = this;
287
287
  if (original) {
288
288
  for (const key in original) {
289
- if (Object.prototype.hasOwnProperty.call(original, key)) {
289
+ if (Object.hasOwn(original, key)) {
290
290
  const element = original[key];
291
291
  entity[key] = element;
292
292
  }
@@ -297,10 +297,7 @@ export default class ChangeEntry<T = any> implements IChanges {
297
297
  }
298
298
 
299
299
  detectDependencies() {
300
- const { type: { fkRelations, inverseRelations }, entity } = this;
301
- // for parent relations.. check if related key is set or not...
302
-
303
- let orderChanged = false;
300
+ const { type: { fkRelations }, entity } = this;
304
301
 
305
302
  for (const iterator of fkRelations) {
306
303
 
@@ -323,70 +320,23 @@ export default class ChangeEntry<T = any> implements IChanges {
323
320
  }
324
321
 
325
322
  const relatedChanges = this.changeSet.getEntry(related);
323
+ this.order += relatedChanges.order + 1;
326
324
 
327
- this.order++;
328
- orderChanged = true;
329
-
330
- if (relatedChanges.status !== "inserted") {
331
- for (const { fkColumn, relatedKeyColumn } of iterator.fkMap) {
332
- this.entity[fkColumn.name] = related[relatedKeyColumn.name];
333
- }
334
- continue;
335
- }
325
+ relatedChanges.detectDependencies();
336
326
 
337
327
  for (const { fkColumn, relatedKeyColumn } of iterator.fkMap) {
338
- // const keyValue = related[relatedKeyColumn.name];
339
- // if (keyValue === void 0 || keyValue === null) {
340
-
341
- // if(relatedChanges.dependents.has(this)) {
342
- // continue;
343
- // }
344
- // relatedChanges.dependents.add(this);
345
-
346
- // for (const d of this.dependents) {
347
- // d.order += this.order + 1;
348
- // }
349
-
350
- // if (!fkColumn.columnName) {
351
- // throw new EntityAccessError(`Configuration error, fk not set for ${fkColumn.name}`);
352
- // }
328
+ const key = related[relatedKeyColumn.name];
329
+ if (key === void 0 || key === null) {
353
330
  relatedChanges.pending.push(() => {
354
- this.entity[fkColumn.name] = related[relatedKeyColumn.name];
331
+ this.setValue(fkColumn, related[relatedKeyColumn.name]);
355
332
  });
356
- // if (this.status !== "inserted") {
357
- // this.modified.set(iterator, { column: fkColumn, oldValue: void 0, newValue: void 0});
358
- // }
359
- // }
360
- // continue;
333
+ } else {
334
+ this.setValue(fkColumn, key);
335
+ }
361
336
  }
362
-
363
-
364
-
365
- // if(!relatedChanges.dependents.has(this)) {
366
- // relatedChanges.dependents.add(this);
367
- // this.order += relatedChanges.order + 1;
368
- // for (const d of this.dependents) {
369
- // d.order += this.order + 1;
370
- // }
371
- // }
372
- // for (const { fkColumn, relatedKeyColumn } of iterator.fkMap) {
373
- // this.entity[fkColumn.name] = related[relatedKeyColumn.name];
374
- // }
375
- // this.entity[iterator.fkColumn.name] = related[rKey.name];
376
337
  }
377
338
 
378
- if (!orderChanged) {
379
- return;
380
- }
381
-
382
- for (const element of inverseRelations) {
383
- const inverseRelation = this[element.name];
384
- if (!inverseRelation) {
385
- continue;
386
- }
387
- // inversely related item can never be an array
388
- this.changeSet.getEntry(inverseRelation).order++;
389
- }
339
+ this.setupInverseProperties();
390
340
  }
391
341
 
392
342
  setupInverseProperties() {
@@ -398,24 +348,67 @@ export default class ChangeEntry<T = any> implements IChanges {
398
348
  continue;
399
349
  }
400
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
+
401
361
  for (const r of related) {
402
- const existing = r[relatedName];
403
- if (existing !== this.entity) {
404
- r[iterator.relatedName] = this.entity;
405
- // need to update order...
406
- this.changeSet.getEntry(r).order++;
407
- }
362
+ this.setInversePropertyValue(r, iterator);
408
363
  }
409
364
  continue;
410
365
  }
411
- if (related[relatedName] !== this.entity) {
412
- related[relatedName] = this.entity;
413
- // need to update order...
414
- this.changeSet.getEntry(related).order++;
415
- }
416
366
  if (deleted) {
417
367
  this.pending.push(() => delete related[relatedName]);
368
+ continue;
418
369
  }
370
+ this.setInversePropertyValue(related, iterator);
419
371
  }
420
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]);
385
+ }
386
+ return;
387
+ }
388
+ this.pending.push(() => {
389
+ for (const { fkColumn , relatedKeyColumn } of relatedRelation.fkMap) {
390
+ re.setValue(fkColumn, entity[relatedKeyColumn.name]);
391
+ }
392
+ });
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
+
421
414
  }
@@ -6,7 +6,6 @@
6
6
 
7
7
  export const filteredSymbol = Symbol("filtered");
8
8
 
9
- const hasOwnProperty = Object.prototype.hasOwnProperty;
10
9
 
11
10
  export const FilteredExpression = {
12
11
  isFiltered(fx): boolean {
@@ -21,7 +20,7 @@ export const FilteredExpression = {
21
20
  }
22
21
  fx[filteredSymbol] = true;
23
22
  for (const key in fx) {
24
- if (hasOwnProperty.call(fx, key)) {
23
+ if (Object.hasOwn(fx, key)) {
25
24
  const element = fx[key];
26
25
  FilteredExpression.markAsFiltered(element);
27
26
  }
@@ -134,7 +134,7 @@ export abstract class Expression {
134
134
  const r = {} as any;
135
135
  Object.setPrototypeOf(r, Object.getPrototypeOf(expression));
136
136
  for (const key in expression) {
137
- if (Object.prototype.hasOwnProperty.call(expression, key)) {
137
+ if (Object.hasOwn(expression, key)) {
138
138
  const element = expression[key];
139
139
  if(Array.isArray(element)) {
140
140
  r[key] = element.map((x) => this.clone(x));
@@ -149,7 +149,7 @@ export abstract class Expression {
149
149
  private static shallowCopy(expression, constants: Expression[]) {
150
150
  const copy = {} as any;
151
151
  for (const key in expression) {
152
- if (Object.prototype.hasOwnProperty.call(expression, key)) {
152
+ if (Object.hasOwn(expression, key)) {
153
153
  const element = expression[key];
154
154
  if (key === "type" || key === "is") {
155
155
  continue;
@@ -27,7 +27,7 @@ export default class ReplaceParameter {
27
27
  }
28
28
  const treeCopy = {} as any;
29
29
  for (const key in tree) {
30
- if (Object.prototype.hasOwnProperty.call(tree, key)) {
30
+ if (Object.hasOwn(tree as any, key)) {
31
31
  const element = tree[key];
32
32
  if (element && typeof element === "object") {
33
33
  treeCopy[key] = this.replace(element, from, to);
package/tsconfig.json CHANGED
@@ -9,6 +9,7 @@
9
9
  "importHelpers": true,
10
10
  "outDir": "dist",
11
11
  "rootDir": "./src",
12
+ "tsBuildInfoFile": "./dist/.tsbuildinfo",
12
13
  "strict": false,
13
14
  "skipDefaultLibCheck": true,
14
15
  "skipLibCheck": true,