@nocobase/database 0.10.0-alpha.2 → 0.10.0-alpha.3
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/lib/repository.js +42 -1
- package/lib/update-guard.js +10 -1
- package/package.json +4 -4
- package/src/__tests__/repository.test.ts +121 -2
- package/src/__tests__/update-guard.test.ts +2 -0
- package/src/repository.ts +39 -0
- package/src/update-guard.ts +12 -2
package/lib/repository.js
CHANGED
|
@@ -39,6 +39,10 @@ function _flat() {
|
|
|
39
39
|
return data;
|
|
40
40
|
}
|
|
41
41
|
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
|
42
|
+
function _slicedToArray(arr, i) { return _arrayWithHoles(arr) || _iterableToArrayLimit(arr, i) || _unsupportedIterableToArray(arr, i) || _nonIterableRest(); }
|
|
43
|
+
function _nonIterableRest() { throw new TypeError("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); }
|
|
44
|
+
function _iterableToArrayLimit(arr, i) { var _i = null == arr ? null : "undefined" != typeof Symbol && arr[Symbol.iterator] || arr["@@iterator"]; if (null != _i) { var _s, _e, _x, _r, _arr = [], _n = !0, _d = !1; try { if (_x = (_i = _i.call(arr)).next, 0 === i) { if (Object(_i) !== _i) return; _n = !1; } else for (; !(_n = (_s = _x.call(_i)).done) && (_arr.push(_s.value), _arr.length !== i); _n = !0); } catch (err) { _d = !0, _e = err; } finally { try { if (!_n && null != _i.return && (_r = _i.return(), Object(_r) !== _r)) return; } finally { if (_d) throw _e; } } return _arr; } }
|
|
45
|
+
function _arrayWithHoles(arr) { if (Array.isArray(arr)) return arr; }
|
|
42
46
|
function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); enumerableOnly && (symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; })), keys.push.apply(keys, symbols); } return keys; }
|
|
43
47
|
function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = null != arguments[i] ? arguments[i] : {}; i % 2 ? ownKeys(Object(source), !0).forEach(function (key) { _defineProperty(target, key, source[key]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)) : ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } return target; }
|
|
44
48
|
function _defineProperty(obj, key, value) { key = _toPropertyKey(key); if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
|
|
@@ -46,7 +50,7 @@ function _toPropertyKey(arg) { var key = _toPrimitive(arg, "string"); return typ
|
|
|
46
50
|
function _toPrimitive(input, hint) { if (typeof input !== "object" || input === null) return input; var prim = input[Symbol.toPrimitive]; if (prim !== undefined) { var res = prim.call(input, hint || "default"); if (typeof res !== "object") return res; throw new TypeError("@@toPrimitive must return a primitive value."); } return (hint === "string" ? String : Number)(input); }
|
|
47
51
|
function asyncGeneratorStep(gen, resolve, reject, _next, _throw, key, arg) { try { var info = gen[key](arg); var value = info.value; } catch (error) { reject(error); return; } if (info.done) { resolve(value); } else { Promise.resolve(value).then(_next, _throw); } }
|
|
48
52
|
function _asyncToGenerator(fn) { return function () { var self = this, args = arguments; return new Promise(function (resolve, reject) { var gen = fn.apply(self, args); function _next(value) { asyncGeneratorStep(gen, resolve, reject, _next, _throw, "next", value); } function _throw(err) { asyncGeneratorStep(gen, resolve, reject, _next, _throw, "throw", err); } _next(undefined); }); }; }
|
|
49
|
-
function _createForOfIteratorHelper(o, allowArrayLike) { var it = typeof Symbol !== "undefined" && o[Symbol.iterator] || o["@@iterator"]; if (!it) { if (Array.isArray(o) || (it = _unsupportedIterableToArray(o)) || allowArrayLike && o && typeof o.length === "number") { if (it) o = it; var i = 0; var F = function F() {}; return { s: F, n: function n() { if (i >= o.length) return { done: true }; return { done: false, value: o[i++] }; }, e: function e(
|
|
53
|
+
function _createForOfIteratorHelper(o, allowArrayLike) { var it = typeof Symbol !== "undefined" && o[Symbol.iterator] || o["@@iterator"]; if (!it) { if (Array.isArray(o) || (it = _unsupportedIterableToArray(o)) || allowArrayLike && o && typeof o.length === "number") { if (it) o = it; var i = 0; var F = function F() {}; return { s: F, n: function n() { if (i >= o.length) return { done: true }; return { done: false, value: o[i++] }; }, e: function e(_e2) { throw _e2; }, f: F }; } throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); } var normalCompletion = true, didErr = false, err; return { s: function s() { it = it.call(o); }, n: function n() { var step = it.next(); normalCompletion = step.done; return step; }, e: function e(_e3) { didErr = true; err = _e3; }, f: function f() { try { if (!normalCompletion && it.return != null) it.return(); } finally { if (didErr) throw err; } } }; }
|
|
50
54
|
function _unsupportedIterableToArray(o, minLen) { if (!o) return; if (typeof o === "string") return _arrayLikeToArray(o, minLen); var n = Object.prototype.toString.call(o).slice(8, -1); if (n === "Object" && o.constructor) n = o.constructor.name; if (n === "Map" || n === "Set") return Array.from(o); if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen); }
|
|
51
55
|
function _arrayLikeToArray(arr, len) { if (len == null || len > arr.length) len = arr.length; for (var i = 0, arr2 = new Array(len); i < len; i++) arr2[i] = arr[i]; return arr2; }
|
|
52
56
|
var __decorate = void 0 && (void 0).__decorate || function (decorators, target, key, desc) {
|
|
@@ -454,6 +458,43 @@ class Repository {
|
|
|
454
458
|
}));
|
|
455
459
|
const values = guard.sanitize(options.values);
|
|
456
460
|
const queryOptions = _this10.buildQueryOptions(options);
|
|
461
|
+
// NOTE:
|
|
462
|
+
// 1. better to be moved to separated API like bulkUpdate/updateMany
|
|
463
|
+
// 2. strictly `false` comparing for compatibility of legacy api invoking
|
|
464
|
+
if (options.individualHooks === false) {
|
|
465
|
+
const Model = _this10.collection.model;
|
|
466
|
+
// @ts-ignore
|
|
467
|
+
const primaryKeyField = Model.primaryKeyField || Model.primaryKeyAttribute;
|
|
468
|
+
// NOTE:
|
|
469
|
+
// 1. find ids first for reusing `queryOptions` logic
|
|
470
|
+
// 2. estimation memory usage will be N * M bytes (N = rows, M = model object memory)
|
|
471
|
+
// 3. would be more efficient up to 100000 ~ 1000000 rows
|
|
472
|
+
const rows = yield Model.findAll(_objectSpread(_objectSpread({}, queryOptions), {}, {
|
|
473
|
+
attributes: [primaryKeyField],
|
|
474
|
+
group: `${Model.name}.${primaryKeyField}`,
|
|
475
|
+
include: queryOptions.include.filter(include => {
|
|
476
|
+
var _JSON$stringify3;
|
|
477
|
+
return Object.keys(include.where || {}).length > 0 || ((_JSON$stringify3 = JSON.stringify(queryOptions === null || queryOptions === void 0 ? void 0 : queryOptions.filter)) === null || _JSON$stringify3 === void 0 ? void 0 : _JSON$stringify3.includes(include.association));
|
|
478
|
+
}),
|
|
479
|
+
transaction
|
|
480
|
+
}));
|
|
481
|
+
const _yield$Model$update = yield Model.update(values, {
|
|
482
|
+
where: {
|
|
483
|
+
[primaryKeyField]: rows.map(row => row.get(primaryKeyField))
|
|
484
|
+
},
|
|
485
|
+
fields: options.fields,
|
|
486
|
+
hooks: options.hooks,
|
|
487
|
+
validate: options.validate,
|
|
488
|
+
sideEffects: options.sideEffects,
|
|
489
|
+
limit: options.limit,
|
|
490
|
+
silent: options.silent,
|
|
491
|
+
transaction
|
|
492
|
+
}),
|
|
493
|
+
_yield$Model$update2 = _slicedToArray(_yield$Model$update, 1),
|
|
494
|
+
result = _yield$Model$update2[0];
|
|
495
|
+
// TODO: not support association fields except belongsTo
|
|
496
|
+
return result;
|
|
497
|
+
}
|
|
457
498
|
const instances = yield _this10.find(_objectSpread(_objectSpread({}, queryOptions), {}, {
|
|
458
499
|
transaction
|
|
459
500
|
}));
|
package/lib/update-guard.js
CHANGED
|
@@ -78,6 +78,7 @@ class UpdateGuard {
|
|
|
78
78
|
// sanitize association values
|
|
79
79
|
Object.keys(associationsValues).forEach(association => {
|
|
80
80
|
let associationValues = associationsValues[association];
|
|
81
|
+
const associationObj = associations[association];
|
|
81
82
|
const filterAssociationToBeUpdate = value => {
|
|
82
83
|
if (value === null) {
|
|
83
84
|
return value;
|
|
@@ -86,7 +87,6 @@ class UpdateGuard {
|
|
|
86
87
|
if (associationKeysToBeUpdate.includes(association)) {
|
|
87
88
|
return value;
|
|
88
89
|
}
|
|
89
|
-
const associationObj = associations[association];
|
|
90
90
|
const associationKeyName = associationObj.associationType == 'BelongsTo' || associationObj.associationType == 'HasOne' ? associationObj.targetKey : associationObj.target.primaryKeyAttribute;
|
|
91
91
|
if (value[associationKeyName]) {
|
|
92
92
|
return _lodash().default.pick(value, [associationKeyName, ...Object.keys(associationObj.target.associations)]);
|
|
@@ -114,6 +114,15 @@ class UpdateGuard {
|
|
|
114
114
|
}
|
|
115
115
|
// set association values to sanitized value
|
|
116
116
|
values[association] = associationValues;
|
|
117
|
+
if (associationObj.associationType === 'BelongsTo') {
|
|
118
|
+
if (typeof associationValues === 'object' && associationValues !== null) {
|
|
119
|
+
if (associationValues[associationObj.targetKey] != null) {
|
|
120
|
+
values[associationObj.foreignKey] = associationValues[associationObj.targetKey];
|
|
121
|
+
}
|
|
122
|
+
} else {
|
|
123
|
+
values[associationObj.foreignKey] = associationValues;
|
|
124
|
+
}
|
|
125
|
+
}
|
|
117
126
|
});
|
|
118
127
|
if (values instanceof _model.Model) {
|
|
119
128
|
return values;
|
package/package.json
CHANGED
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@nocobase/database",
|
|
3
|
-
"version": "0.10.0-alpha.
|
|
3
|
+
"version": "0.10.0-alpha.3",
|
|
4
4
|
"description": "",
|
|
5
5
|
"main": "./lib/index.js",
|
|
6
6
|
"types": "./lib/index.d.ts",
|
|
7
7
|
"license": "Apache-2.0",
|
|
8
8
|
"dependencies": {
|
|
9
|
-
"@nocobase/logger": "0.10.0-alpha.
|
|
10
|
-
"@nocobase/utils": "0.10.0-alpha.
|
|
9
|
+
"@nocobase/logger": "0.10.0-alpha.3",
|
|
10
|
+
"@nocobase/utils": "0.10.0-alpha.3",
|
|
11
11
|
"async-mutex": "^0.3.2",
|
|
12
12
|
"cron-parser": "4.4.0",
|
|
13
13
|
"deepmerge": "^4.2.2",
|
|
@@ -28,5 +28,5 @@
|
|
|
28
28
|
"url": "git+https://github.com/nocobase/nocobase.git",
|
|
29
29
|
"directory": "packages/database"
|
|
30
30
|
},
|
|
31
|
-
"gitHead": "
|
|
31
|
+
"gitHead": "1f0b27fc9ab2398cd41c308a6b01a986e025cd20"
|
|
32
32
|
}
|
|
@@ -398,6 +398,7 @@ describe('repository.update', () => {
|
|
|
398
398
|
fields: [
|
|
399
399
|
{ type: 'string', name: 'name' },
|
|
400
400
|
{ type: 'hasMany', name: 'comments' },
|
|
401
|
+
{ type: 'belongsTo', name: 'user' },
|
|
401
402
|
],
|
|
402
403
|
});
|
|
403
404
|
Comment = db.collection({
|
|
@@ -411,7 +412,7 @@ describe('repository.update', () => {
|
|
|
411
412
|
await db.close();
|
|
412
413
|
});
|
|
413
414
|
|
|
414
|
-
it('
|
|
415
|
+
it('update with filterByTk and with associations', async () => {
|
|
415
416
|
const user = await User.model.create<any>({
|
|
416
417
|
name: 'user1',
|
|
417
418
|
});
|
|
@@ -454,7 +455,7 @@ describe('repository.update', () => {
|
|
|
454
455
|
expect(updated2.posts.length).toBe(2);
|
|
455
456
|
});
|
|
456
457
|
|
|
457
|
-
it('
|
|
458
|
+
it('update with filterByTk', async () => {
|
|
458
459
|
const user = await User.model.create<any>({
|
|
459
460
|
name: 'user1',
|
|
460
461
|
});
|
|
@@ -463,6 +464,9 @@ describe('repository.update', () => {
|
|
|
463
464
|
name: 'user2',
|
|
464
465
|
});
|
|
465
466
|
|
|
467
|
+
const hook = jest.fn();
|
|
468
|
+
db.on('users.afterUpdate', hook);
|
|
469
|
+
|
|
466
470
|
await User.repository.update({
|
|
467
471
|
filterByTk: user.id,
|
|
468
472
|
values: {
|
|
@@ -470,6 +474,8 @@ describe('repository.update', () => {
|
|
|
470
474
|
},
|
|
471
475
|
});
|
|
472
476
|
|
|
477
|
+
expect(hook).toBeCalledTimes(1);
|
|
478
|
+
|
|
473
479
|
const updated = await User.model.findByPk(user.id);
|
|
474
480
|
|
|
475
481
|
expect(updated.get('name')).toEqual('user11');
|
|
@@ -477,6 +483,119 @@ describe('repository.update', () => {
|
|
|
477
483
|
const u2 = await User.model.findByPk(user2.id);
|
|
478
484
|
expect(u2.get('name')).toEqual('user2');
|
|
479
485
|
});
|
|
486
|
+
|
|
487
|
+
it('update with filter one by one when individualHooks is not set', async () => {
|
|
488
|
+
const u1 = await User.repository.create({ values: { name: 'u1' } });
|
|
489
|
+
|
|
490
|
+
const p1 = await Post.repository.create({ values: { name: 'p1', userId: u1.id } });
|
|
491
|
+
const p2 = await Post.repository.create({ values: { name: 'p2', userId: u1.id } });
|
|
492
|
+
const p3 = await Post.repository.create({ values: { name: 'p3' } });
|
|
493
|
+
|
|
494
|
+
const hook = jest.fn();
|
|
495
|
+
db.on('posts.afterUpdate', hook);
|
|
496
|
+
|
|
497
|
+
await Post.repository.update({
|
|
498
|
+
filter: {
|
|
499
|
+
userId: u1.id,
|
|
500
|
+
},
|
|
501
|
+
values: {
|
|
502
|
+
name: 'pp',
|
|
503
|
+
},
|
|
504
|
+
});
|
|
505
|
+
|
|
506
|
+
const postsAfterUpdated = await Post.repository.find({ order: [['id', 'ASC']] });
|
|
507
|
+
expect(postsAfterUpdated[0].name).toBe('pp');
|
|
508
|
+
expect(postsAfterUpdated[1].name).toBe('pp');
|
|
509
|
+
expect(postsAfterUpdated[2].name).toBe('p3');
|
|
510
|
+
|
|
511
|
+
expect(hook).toBeCalledTimes(2);
|
|
512
|
+
});
|
|
513
|
+
|
|
514
|
+
it('update in batch when individualHooks is false', async () => {
|
|
515
|
+
const u1 = await User.repository.create({ values: { name: 'u1' } });
|
|
516
|
+
|
|
517
|
+
const p1 = await Post.repository.create({ values: { name: 'p1', userId: u1.id } });
|
|
518
|
+
const p2 = await Post.repository.create({ values: { name: 'p2', userId: u1.id } });
|
|
519
|
+
const p3 = await Post.repository.create({ values: { name: 'p3' } });
|
|
520
|
+
|
|
521
|
+
const hook = jest.fn();
|
|
522
|
+
db.on('posts.afterUpdate', hook);
|
|
523
|
+
|
|
524
|
+
await Post.repository.update({
|
|
525
|
+
filter: {
|
|
526
|
+
userId: u1.id,
|
|
527
|
+
},
|
|
528
|
+
values: {
|
|
529
|
+
name: 'pp',
|
|
530
|
+
},
|
|
531
|
+
individualHooks: false,
|
|
532
|
+
});
|
|
533
|
+
|
|
534
|
+
const postsAfterUpdated = await Post.repository.find({ order: [['id', 'ASC']] });
|
|
535
|
+
expect(postsAfterUpdated[0].name).toBe('pp');
|
|
536
|
+
expect(postsAfterUpdated[1].name).toBe('pp');
|
|
537
|
+
expect(postsAfterUpdated[2].name).toBe('p3');
|
|
538
|
+
|
|
539
|
+
expect(hook).toBeCalledTimes(0);
|
|
540
|
+
});
|
|
541
|
+
|
|
542
|
+
it('update in batch with belongsTo field as foreignKey', async () => {
|
|
543
|
+
const u1 = await User.repository.create({ values: { name: 'u1' } });
|
|
544
|
+
const u2 = await User.repository.create({ values: { name: 'u2' } });
|
|
545
|
+
const p1 = await Post.repository.create({ values: { name: 'p1', userId: u1.id } });
|
|
546
|
+
const p2 = await Post.repository.create({ values: { name: 'p2', userId: u1.id } });
|
|
547
|
+
|
|
548
|
+
const r1 = await Post.repository.update({
|
|
549
|
+
filter: {
|
|
550
|
+
name: p1.name,
|
|
551
|
+
},
|
|
552
|
+
values: {
|
|
553
|
+
user: u2.id,
|
|
554
|
+
},
|
|
555
|
+
individualHooks: false,
|
|
556
|
+
});
|
|
557
|
+
|
|
558
|
+
expect(r1).toEqual(1);
|
|
559
|
+
|
|
560
|
+
const p1Updated = await Post.repository.findOne({
|
|
561
|
+
filterByTk: p1.id,
|
|
562
|
+
});
|
|
563
|
+
expect(p1Updated.userId).toBe(u2.id);
|
|
564
|
+
|
|
565
|
+
const r2 = await Post.repository.update({
|
|
566
|
+
filter: {
|
|
567
|
+
id: p2.id,
|
|
568
|
+
},
|
|
569
|
+
values: {
|
|
570
|
+
user: null,
|
|
571
|
+
},
|
|
572
|
+
individualHooks: false,
|
|
573
|
+
});
|
|
574
|
+
|
|
575
|
+
expect(r2).toEqual(1);
|
|
576
|
+
|
|
577
|
+
const p2Updated = await Post.repository.findOne({
|
|
578
|
+
filterByTk: p2.id,
|
|
579
|
+
});
|
|
580
|
+
expect(p2Updated.userId).toBe(null);
|
|
581
|
+
|
|
582
|
+
const r3 = await Post.repository.update({
|
|
583
|
+
filter: {
|
|
584
|
+
id: p1.id,
|
|
585
|
+
},
|
|
586
|
+
values: {
|
|
587
|
+
user: { id: u1.id },
|
|
588
|
+
},
|
|
589
|
+
individualHooks: false,
|
|
590
|
+
});
|
|
591
|
+
|
|
592
|
+
expect(r3).toEqual(1);
|
|
593
|
+
|
|
594
|
+
const p1Updated2 = await Post.repository.findOne({
|
|
595
|
+
filterByTk: p1.id,
|
|
596
|
+
});
|
|
597
|
+
expect(p1Updated2.userId).toBe(u1.id);
|
|
598
|
+
});
|
|
480
599
|
});
|
|
481
600
|
|
|
482
601
|
describe('repository.destroy', () => {
|
|
@@ -370,6 +370,7 @@ describe('One2One Association', () => {
|
|
|
370
370
|
uid: 1,
|
|
371
371
|
name: '123',
|
|
372
372
|
},
|
|
373
|
+
userId: 1,
|
|
373
374
|
};
|
|
374
375
|
|
|
375
376
|
const guard = new UpdateGuard();
|
|
@@ -381,6 +382,7 @@ describe('One2One Association', () => {
|
|
|
381
382
|
user: {
|
|
382
383
|
uid: 1,
|
|
383
384
|
},
|
|
385
|
+
userId: 1,
|
|
384
386
|
});
|
|
385
387
|
|
|
386
388
|
guard.setAssociationKeysToBeUpdate(['user']);
|
package/src/repository.ts
CHANGED
|
@@ -609,6 +609,45 @@ export class Repository<TModelAttributes extends {} = any, TCreationAttributes e
|
|
|
609
609
|
|
|
610
610
|
const queryOptions = this.buildQueryOptions(options);
|
|
611
611
|
|
|
612
|
+
// NOTE:
|
|
613
|
+
// 1. better to be moved to separated API like bulkUpdate/updateMany
|
|
614
|
+
// 2. strictly `false` comparing for compatibility of legacy api invoking
|
|
615
|
+
if (options.individualHooks === false) {
|
|
616
|
+
const { model: Model } = this.collection;
|
|
617
|
+
// @ts-ignore
|
|
618
|
+
const primaryKeyField = Model.primaryKeyField || Model.primaryKeyAttribute;
|
|
619
|
+
// NOTE:
|
|
620
|
+
// 1. find ids first for reusing `queryOptions` logic
|
|
621
|
+
// 2. estimation memory usage will be N * M bytes (N = rows, M = model object memory)
|
|
622
|
+
// 3. would be more efficient up to 100000 ~ 1000000 rows
|
|
623
|
+
const rows = await Model.findAll({
|
|
624
|
+
...queryOptions,
|
|
625
|
+
attributes: [primaryKeyField],
|
|
626
|
+
group: `${Model.name}.${primaryKeyField}`,
|
|
627
|
+
include: queryOptions.include.filter((include) => {
|
|
628
|
+
return (
|
|
629
|
+
Object.keys(include.where || {}).length > 0 ||
|
|
630
|
+
JSON.stringify(queryOptions?.filter)?.includes(include.association)
|
|
631
|
+
);
|
|
632
|
+
}),
|
|
633
|
+
transaction,
|
|
634
|
+
});
|
|
635
|
+
const [result] = await Model.update(values, {
|
|
636
|
+
where: {
|
|
637
|
+
[primaryKeyField]: rows.map((row) => row.get(primaryKeyField)),
|
|
638
|
+
},
|
|
639
|
+
fields: options.fields,
|
|
640
|
+
hooks: options.hooks,
|
|
641
|
+
validate: options.validate,
|
|
642
|
+
sideEffects: options.sideEffects,
|
|
643
|
+
limit: options.limit,
|
|
644
|
+
silent: options.silent,
|
|
645
|
+
transaction,
|
|
646
|
+
});
|
|
647
|
+
// TODO: not support association fields except belongsTo
|
|
648
|
+
return result;
|
|
649
|
+
}
|
|
650
|
+
|
|
612
651
|
const instances = await this.find({
|
|
613
652
|
...queryOptions,
|
|
614
653
|
transaction,
|
package/src/update-guard.ts
CHANGED
|
@@ -93,6 +93,8 @@ export class UpdateGuard {
|
|
|
93
93
|
Object.keys(associationsValues).forEach((association) => {
|
|
94
94
|
let associationValues = associationsValues[association];
|
|
95
95
|
|
|
96
|
+
const associationObj = associations[association];
|
|
97
|
+
|
|
96
98
|
const filterAssociationToBeUpdate = (value) => {
|
|
97
99
|
if (value === null) {
|
|
98
100
|
return value;
|
|
@@ -104,8 +106,6 @@ export class UpdateGuard {
|
|
|
104
106
|
return value;
|
|
105
107
|
}
|
|
106
108
|
|
|
107
|
-
const associationObj = associations[association];
|
|
108
|
-
|
|
109
109
|
const associationKeyName =
|
|
110
110
|
associationObj.associationType == 'BelongsTo' || associationObj.associationType == 'HasOne'
|
|
111
111
|
? (<any>associationObj).targetKey
|
|
@@ -143,6 +143,16 @@ export class UpdateGuard {
|
|
|
143
143
|
|
|
144
144
|
// set association values to sanitized value
|
|
145
145
|
values[association] = associationValues;
|
|
146
|
+
|
|
147
|
+
if (associationObj.associationType === 'BelongsTo') {
|
|
148
|
+
if (typeof associationValues === 'object' && associationValues !== null) {
|
|
149
|
+
if (associationValues[(associationObj as any).targetKey] != null) {
|
|
150
|
+
values[(associationObj as any).foreignKey] = associationValues[(associationObj as any).targetKey];
|
|
151
|
+
}
|
|
152
|
+
} else {
|
|
153
|
+
values[(associationObj as any).foreignKey] = associationValues;
|
|
154
|
+
}
|
|
155
|
+
}
|
|
146
156
|
});
|
|
147
157
|
|
|
148
158
|
if (values instanceof Model) {
|