@tachybase/database 0.23.20 → 0.23.35
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.
|
@@ -107,17 +107,17 @@ const _EagerLoadingTree = class _EagerLoadingTree {
|
|
|
107
107
|
children: [],
|
|
108
108
|
includeOption: include.options || {}
|
|
109
109
|
});
|
|
110
|
-
if (associationType
|
|
110
|
+
if (associationType === "HasOne" || associationType === "HasMany") {
|
|
111
111
|
const { sourceKey, foreignKey } = association;
|
|
112
112
|
pushAttribute(eagerLoadingTreeParent, sourceKey);
|
|
113
113
|
pushAttribute(child, foreignKey);
|
|
114
114
|
}
|
|
115
|
-
if (associationType
|
|
115
|
+
if (associationType === "BelongsTo") {
|
|
116
116
|
const { targetKey, foreignKey } = association;
|
|
117
117
|
pushAttribute(eagerLoadingTreeParent, foreignKey);
|
|
118
118
|
pushAttribute(child, targetKey);
|
|
119
119
|
}
|
|
120
|
-
if (associationType
|
|
120
|
+
if (associationType === "BelongsToMany") {
|
|
121
121
|
const { sourceKey } = association;
|
|
122
122
|
pushAttribute(eagerLoadingTreeParent, sourceKey);
|
|
123
123
|
}
|
|
@@ -144,21 +144,40 @@ const _EagerLoadingTree = class _EagerLoadingTree {
|
|
|
144
144
|
return order;
|
|
145
145
|
}, "orderOption");
|
|
146
146
|
const loadRecursive = /* @__PURE__ */ __name(async (node, ids = []) => {
|
|
147
|
-
var _a;
|
|
147
|
+
var _a, _b;
|
|
148
148
|
let instances = [];
|
|
149
149
|
if (!node.parent) {
|
|
150
150
|
const rootInclude = ((_a = this.rootQueryOptions) == null ? void 0 : _a.include) || node.includeOption;
|
|
151
151
|
const includeForFilter = rootInclude.filter((include) => {
|
|
152
|
-
var _a2,
|
|
153
|
-
return Object.keys(include.where || {}).length > 0 || ((
|
|
152
|
+
var _a2, _b2;
|
|
153
|
+
return Object.keys(include.where || {}).length > 0 || ((_b2 = JSON.stringify((_a2 = this.rootQueryOptions) == null ? void 0 : _a2.filter)) == null ? void 0 : _b2.includes(include.association));
|
|
154
154
|
});
|
|
155
|
+
const sortModelSet = /* @__PURE__ */ new Set();
|
|
156
|
+
if ((_b = this.rootQueryOptions) == null ? void 0 : _b.order) {
|
|
157
|
+
for (const order of this.rootQueryOptions.order) {
|
|
158
|
+
for (const field of order) {
|
|
159
|
+
if (field.as) {
|
|
160
|
+
sortModelSet.add(field.as);
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
const inCludeForSort = [];
|
|
166
|
+
for (const sortModel of sortModelSet) {
|
|
167
|
+
if (includeForFilter.find((v) => v.association === sortModel)) {
|
|
168
|
+
continue;
|
|
169
|
+
}
|
|
170
|
+
inCludeForSort.push({
|
|
171
|
+
association: sortModel
|
|
172
|
+
});
|
|
173
|
+
}
|
|
155
174
|
const isBelongsToAssociationOnly = /* @__PURE__ */ __name((includes, model) => {
|
|
156
175
|
for (const include of includes) {
|
|
157
176
|
const association = model.associations[include.association];
|
|
158
177
|
if (!association) {
|
|
159
178
|
return false;
|
|
160
179
|
}
|
|
161
|
-
if (association.associationType
|
|
180
|
+
if (association.associationType !== "BelongsTo") {
|
|
162
181
|
return false;
|
|
163
182
|
}
|
|
164
183
|
if (!isBelongsToAssociationOnly(include.include || [], association.target)) {
|
|
@@ -173,7 +192,7 @@ const _EagerLoadingTree = class _EagerLoadingTree {
|
|
|
173
192
|
...this.rootQueryOptions,
|
|
174
193
|
attributes: node.attributes,
|
|
175
194
|
distinct: true,
|
|
176
|
-
include: includeForFilter,
|
|
195
|
+
include: includeForFilter.concat(inCludeForSort),
|
|
177
196
|
transaction
|
|
178
197
|
});
|
|
179
198
|
} else {
|
|
@@ -187,7 +206,7 @@ const _EagerLoadingTree = class _EagerLoadingTree {
|
|
|
187
206
|
attributes: [primaryKeyField],
|
|
188
207
|
group: `${node.model.name}.${primaryKeyField}`,
|
|
189
208
|
transaction,
|
|
190
|
-
include: includeForFilter
|
|
209
|
+
include: includeForFilter.concat(inCludeForSort)
|
|
191
210
|
})).map((row) => {
|
|
192
211
|
return { row, pk: row[primaryKeyField] };
|
|
193
212
|
});
|
|
@@ -222,7 +241,7 @@ const _EagerLoadingTree = class _EagerLoadingTree {
|
|
|
222
241
|
});
|
|
223
242
|
params = parser.toSequelizeParams();
|
|
224
243
|
}
|
|
225
|
-
if (associationType
|
|
244
|
+
if (associationType === "HasOne" || associationType === "HasMany") {
|
|
226
245
|
const foreignKey = association.foreignKey;
|
|
227
246
|
const foreignKeyValues = node.parent.instances.map((instance) => instance.get(association.sourceKey));
|
|
228
247
|
let where = { [foreignKey]: foreignKeyValues };
|
|
@@ -239,7 +258,7 @@ const _EagerLoadingTree = class _EagerLoadingTree {
|
|
|
239
258
|
};
|
|
240
259
|
instances = await node.model.findAll(findOptions);
|
|
241
260
|
}
|
|
242
|
-
if (associationType
|
|
261
|
+
if (associationType === "BelongsTo") {
|
|
243
262
|
const foreignKey = association.foreignKey;
|
|
244
263
|
const parentInstancesForeignKeyValues = node.parent.instances.map((instance) => instance.get(foreignKey));
|
|
245
264
|
const collection2 = this.db.modelCollection.get(node.model);
|
|
@@ -272,7 +291,7 @@ const _EagerLoadingTree = class _EagerLoadingTree {
|
|
|
272
291
|
});
|
|
273
292
|
const setInstanceParent = /* @__PURE__ */ __name((instance) => {
|
|
274
293
|
const parentInstance = parentInstances.find(
|
|
275
|
-
(parentInstance2) => parentInstance2.get(targetKey)
|
|
294
|
+
(parentInstance2) => parentInstance2.get(targetKey) === instance.get(foreignKey)
|
|
276
295
|
);
|
|
277
296
|
if (!parentInstance) {
|
|
278
297
|
return;
|
|
@@ -285,7 +304,7 @@ const _EagerLoadingTree = class _EagerLoadingTree {
|
|
|
285
304
|
}
|
|
286
305
|
}
|
|
287
306
|
}
|
|
288
|
-
if (associationType
|
|
307
|
+
if (associationType === "BelongsToMany") {
|
|
289
308
|
const foreignKeyValues = node.parent.instances.map((instance) => instance.get(association.sourceKey));
|
|
290
309
|
const hasOneOptions = {
|
|
291
310
|
as: "_pivot_",
|
|
@@ -329,19 +348,19 @@ const _EagerLoadingTree = class _EagerLoadingTree {
|
|
|
329
348
|
const isEmpty = !children;
|
|
330
349
|
parentInstance[key] = parentInstance.dataValues[key] = isEmpty ? null : children;
|
|
331
350
|
} else {
|
|
332
|
-
const isEmpty = !children || children.length
|
|
351
|
+
const isEmpty = !children || children.length === 0;
|
|
333
352
|
parentInstance[key] = parentInstance.dataValues[key] = isEmpty ? [] : children;
|
|
334
353
|
}
|
|
335
354
|
}, "setParentAccessor");
|
|
336
|
-
if (associationType
|
|
355
|
+
if (associationType === "HasMany" || associationType === "HasOne") {
|
|
337
356
|
const foreignKey = association.foreignKey;
|
|
338
357
|
const sourceKey = association.sourceKey;
|
|
339
358
|
for (const instance of node.instances) {
|
|
340
359
|
const parentInstance = node.parent.instances.find(
|
|
341
|
-
(parentInstance2) => parentInstance2.get(sourceKey)
|
|
360
|
+
(parentInstance2) => parentInstance2.get(sourceKey) === instance.get(foreignKey)
|
|
342
361
|
);
|
|
343
362
|
if (parentInstance) {
|
|
344
|
-
if (associationType
|
|
363
|
+
if (associationType === "HasMany") {
|
|
345
364
|
const children = parentInstance.getDataValue(association.as);
|
|
346
365
|
if (!children) {
|
|
347
366
|
parentInstance.setDataValue(association.as, [instance]);
|
|
@@ -349,26 +368,26 @@ const _EagerLoadingTree = class _EagerLoadingTree {
|
|
|
349
368
|
children.push(instance);
|
|
350
369
|
}
|
|
351
370
|
}
|
|
352
|
-
if (associationType
|
|
371
|
+
if (associationType === "HasOne") {
|
|
353
372
|
const key = association.options.realAs || association.as;
|
|
354
373
|
parentInstance[key] = parentInstance.dataValues[key] = instance;
|
|
355
374
|
}
|
|
356
375
|
}
|
|
357
376
|
}
|
|
358
377
|
}
|
|
359
|
-
if (associationType
|
|
378
|
+
if (associationType === "BelongsTo") {
|
|
360
379
|
const foreignKey = association.foreignKey;
|
|
361
380
|
const targetKey = association.targetKey;
|
|
362
381
|
for (const instance of node.instances) {
|
|
363
382
|
const parentInstances = node.parent.instances.filter(
|
|
364
|
-
(parentInstance) => parentInstance.get(foreignKey)
|
|
383
|
+
(parentInstance) => parentInstance.get(foreignKey) === instance.get(targetKey)
|
|
365
384
|
);
|
|
366
385
|
for (const parentInstance of parentInstances) {
|
|
367
386
|
parentInstance.setDataValue(association.as, instance);
|
|
368
387
|
}
|
|
369
388
|
}
|
|
370
389
|
}
|
|
371
|
-
if (associationType
|
|
390
|
+
if (associationType === "BelongsToMany") {
|
|
372
391
|
const sourceKey = association.sourceKey;
|
|
373
392
|
const foreignKey = association.foreignKey;
|
|
374
393
|
const as = association.oneFromTarget.as;
|
|
@@ -377,7 +396,7 @@ const _EagerLoadingTree = class _EagerLoadingTree {
|
|
|
377
396
|
delete instance.dataValues["_pivot_"];
|
|
378
397
|
delete instance["_pivot_"];
|
|
379
398
|
const parentInstance = node.parent.instances.find(
|
|
380
|
-
(parentInstance2) => parentInstance2.get(sourceKey)
|
|
399
|
+
(parentInstance2) => parentInstance2.get(sourceKey) === instance.dataValues[as].get(foreignKey)
|
|
381
400
|
);
|
|
382
401
|
if (parentInstance) {
|
|
383
402
|
const children = parentInstance.getDataValue(association.as);
|
|
@@ -405,7 +424,7 @@ const _EagerLoadingTree = class _EagerLoadingTree {
|
|
|
405
424
|
dataCollection: this.db.modelCollection.get(node.model)
|
|
406
425
|
});
|
|
407
426
|
}
|
|
408
|
-
if (((_a = node.association) == null ? void 0 : _a.as)
|
|
427
|
+
if (((_a = node.association) == null ? void 0 : _a.as) === "_pivot_") {
|
|
409
428
|
return;
|
|
410
429
|
}
|
|
411
430
|
const nodeRawAttributes = node.rawAttributes || [];
|
package/lib/options-parser.d.ts
CHANGED
|
@@ -18,6 +18,7 @@ export declare class OptionsParser {
|
|
|
18
18
|
static appendInheritInspectAttribute(include: any, collection: any): any;
|
|
19
19
|
isAssociation(key: string): boolean;
|
|
20
20
|
isAssociationPath(path: string): boolean;
|
|
21
|
+
filterByTkToWhereOption(): {};
|
|
21
22
|
toSequelizeParams(): any;
|
|
22
23
|
/**
|
|
23
24
|
* parser sort options
|
package/lib/options-parser.js
CHANGED
|
@@ -81,20 +81,40 @@ const _OptionsParser = class _OptionsParser {
|
|
|
81
81
|
isAssociationPath(path) {
|
|
82
82
|
return this.isAssociation(path.split(".")[0]);
|
|
83
83
|
}
|
|
84
|
+
filterByTkToWhereOption() {
|
|
85
|
+
var _a;
|
|
86
|
+
const filterByTkOption = (_a = this.options) == null ? void 0 : _a.filterByTk;
|
|
87
|
+
if (!filterByTkOption) {
|
|
88
|
+
return {};
|
|
89
|
+
}
|
|
90
|
+
if (import_lodash.default.isPlainObject(this.options.filterByTk)) {
|
|
91
|
+
const where = {};
|
|
92
|
+
for (const [key, value] of Object.entries(filterByTkOption)) {
|
|
93
|
+
where[key] = value;
|
|
94
|
+
}
|
|
95
|
+
return where;
|
|
96
|
+
}
|
|
97
|
+
const filterTargetKey = this.context.targetKey || this.collection.filterTargetKey;
|
|
98
|
+
if (Array.isArray(filterTargetKey)) {
|
|
99
|
+
throw new Error("multi filter target key value must be object");
|
|
100
|
+
}
|
|
101
|
+
return {
|
|
102
|
+
[filterTargetKey]: filterByTkOption
|
|
103
|
+
};
|
|
104
|
+
}
|
|
84
105
|
toSequelizeParams() {
|
|
85
|
-
var _a, _b;
|
|
106
|
+
var _a, _b, _c;
|
|
86
107
|
const queryParams = this.filterParser.toSequelizeParams();
|
|
87
108
|
if ((_a = this.options) == null ? void 0 : _a.filterByTk) {
|
|
109
|
+
const filterByTkWhere = this.filterByTkToWhereOption();
|
|
88
110
|
queryParams.where = {
|
|
89
|
-
[import_sequelize.Op.and]: [
|
|
90
|
-
queryParams.where,
|
|
91
|
-
{
|
|
92
|
-
[this.context.targetKey || this.collection.filterTargetKey]: this.options.filterByTk
|
|
93
|
-
}
|
|
94
|
-
]
|
|
111
|
+
[import_sequelize.Op.and]: [queryParams.where, filterByTkWhere]
|
|
95
112
|
};
|
|
96
113
|
}
|
|
97
|
-
if ((_b = this.options) == null ? void 0 : _b.include) {
|
|
114
|
+
if (queryParams.include && !((_b = this.options) == null ? void 0 : _b.include)) {
|
|
115
|
+
this.options.include = [];
|
|
116
|
+
}
|
|
117
|
+
if ((_c = this.options) == null ? void 0 : _c.include) {
|
|
98
118
|
if (!queryParams.include) {
|
|
99
119
|
queryParams.include = [];
|
|
100
120
|
}
|
|
@@ -108,32 +128,66 @@ const _OptionsParser = class _OptionsParser {
|
|
|
108
128
|
* @protected
|
|
109
129
|
*/
|
|
110
130
|
parseSort(filterParams) {
|
|
111
|
-
var _a;
|
|
131
|
+
var _a, _b;
|
|
112
132
|
let sort = ((_a = this.options) == null ? void 0 : _a.sort) || [];
|
|
113
133
|
if (typeof sort === "string") {
|
|
114
134
|
sort = sort.split(",");
|
|
115
135
|
}
|
|
136
|
+
let defaultSortField = this.model.primaryKeyAttribute;
|
|
137
|
+
if (Array.isArray(this.collection.filterTargetKey)) {
|
|
138
|
+
defaultSortField = this.collection.filterTargetKey;
|
|
139
|
+
}
|
|
140
|
+
if (!defaultSortField && this.collection.filterTargetKey && !Array.isArray(this.collection.filterTargetKey)) {
|
|
141
|
+
defaultSortField = this.collection.filterTargetKey;
|
|
142
|
+
}
|
|
143
|
+
if (defaultSortField && !((_b = this.options) == null ? void 0 : _b.group)) {
|
|
144
|
+
defaultSortField = import_lodash.default.castArray(defaultSortField);
|
|
145
|
+
for (const key of defaultSortField) {
|
|
146
|
+
if (!sort.includes(key)) {
|
|
147
|
+
sort.push(key);
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
}
|
|
116
151
|
const orderParams = [];
|
|
117
152
|
for (const sortKey of sort) {
|
|
118
153
|
let direction = sortKey.startsWith("-") ? "DESC" : "ASC";
|
|
119
|
-
const sortField = sortKey.replace("-", "").split(".");
|
|
154
|
+
const sortField = sortKey.startsWith("-") ? sortKey.replace("-", "").split(".") : sortKey.split(".");
|
|
120
155
|
if (this.database.inDialect("postgres", "sqlite")) {
|
|
121
156
|
direction = `${direction} NULLS LAST`;
|
|
122
157
|
}
|
|
158
|
+
let valid = true;
|
|
123
159
|
if (sortField.length > 1) {
|
|
124
160
|
let associationModel = this.model;
|
|
125
161
|
for (let i = 0; i < sortField.length - 1; i++) {
|
|
126
162
|
const associationKey = sortField[i];
|
|
127
|
-
|
|
128
|
-
|
|
163
|
+
const associationEntity = associationModel.associations[associationKey];
|
|
164
|
+
if (!associationEntity) {
|
|
165
|
+
valid = false;
|
|
166
|
+
break;
|
|
167
|
+
}
|
|
168
|
+
if (!["BelongsTo", "HasOne"].includes(associationEntity.associationType)) {
|
|
169
|
+
continue;
|
|
170
|
+
}
|
|
171
|
+
const model = associationEntity.target;
|
|
172
|
+
sortField[i] = {
|
|
173
|
+
model,
|
|
174
|
+
as: associationKey
|
|
175
|
+
};
|
|
176
|
+
associationModel = model;
|
|
129
177
|
}
|
|
130
178
|
} else {
|
|
131
179
|
const rawField = this.model.rawAttributes[sortField[0]];
|
|
132
180
|
sortField[0] = (rawField == null ? void 0 : rawField.field) || sortField[0];
|
|
133
181
|
}
|
|
182
|
+
if (!valid) {
|
|
183
|
+
continue;
|
|
184
|
+
}
|
|
134
185
|
sortField.push(direction);
|
|
135
186
|
if (this.database.isMySQLCompatibleDialect()) {
|
|
136
|
-
|
|
187
|
+
const fieldName = sortField[0];
|
|
188
|
+
if (this.model.fieldRawAttributesMap[fieldName]) {
|
|
189
|
+
orderParams.push([import_sequelize.Sequelize.fn("ISNULL", import_sequelize.Sequelize.col(`${this.model.name}.${sortField[0]}`))]);
|
|
190
|
+
}
|
|
137
191
|
}
|
|
138
192
|
orderParams.push(sortField);
|
|
139
193
|
}
|
|
@@ -195,8 +249,8 @@ const _OptionsParser = class _OptionsParser {
|
|
|
195
249
|
const exceptPath = except2.split(".");
|
|
196
250
|
const association = exceptPath[0];
|
|
197
251
|
const lastLevel = exceptPath.length <= 2;
|
|
198
|
-
const existIncludeIndex = queryParams["include"].findIndex((include) => include["association"]
|
|
199
|
-
if (existIncludeIndex
|
|
252
|
+
const existIncludeIndex = queryParams["include"].findIndex((include) => include["association"] === association);
|
|
253
|
+
if (existIncludeIndex === -1) {
|
|
200
254
|
return;
|
|
201
255
|
}
|
|
202
256
|
if (lastLevel) {
|
|
@@ -240,10 +294,10 @@ const _OptionsParser = class _OptionsParser {
|
|
|
240
294
|
const appendAssociation = appendFields[0];
|
|
241
295
|
const associations = model.associations;
|
|
242
296
|
let lastLevel = false;
|
|
243
|
-
if (appendFields.length
|
|
297
|
+
if (appendFields.length === 1) {
|
|
244
298
|
lastLevel = true;
|
|
245
299
|
}
|
|
246
|
-
if (appendFields.length
|
|
300
|
+
if (appendFields.length === 2) {
|
|
247
301
|
const association = associations[appendFields[0]];
|
|
248
302
|
if (!association) {
|
|
249
303
|
throw new Error(`association ${appendFields[0]} in ${model.name} not found`);
|
|
@@ -253,24 +307,24 @@ const _OptionsParser = class _OptionsParser {
|
|
|
253
307
|
lastLevel = true;
|
|
254
308
|
}
|
|
255
309
|
}
|
|
256
|
-
if (queryParams["include"]
|
|
310
|
+
if (queryParams["include"] === void 0) {
|
|
257
311
|
queryParams["include"] = [];
|
|
258
312
|
}
|
|
259
313
|
let existIncludeIndex = queryParams["include"].findIndex(
|
|
260
|
-
(include) => include["association"]
|
|
314
|
+
(include) => include["association"] === appendAssociation
|
|
261
315
|
);
|
|
262
|
-
if (existIncludeIndex
|
|
316
|
+
if (existIncludeIndex !== -1) {
|
|
263
317
|
delete queryParams["include"][existIncludeIndex]["fromFilter"];
|
|
264
|
-
if (Array.isArray(queryParams["include"][existIncludeIndex]["attributes"]) && queryParams["include"][existIncludeIndex]["attributes"].length
|
|
318
|
+
if (Array.isArray(queryParams["include"][existIncludeIndex]["attributes"]) && queryParams["include"][existIncludeIndex]["attributes"].length === 0) {
|
|
265
319
|
queryParams["include"][existIncludeIndex]["attributes"] = {
|
|
266
320
|
include: []
|
|
267
321
|
};
|
|
268
322
|
}
|
|
269
323
|
}
|
|
270
|
-
if (lastLevel && existIncludeIndex
|
|
324
|
+
if (lastLevel && existIncludeIndex !== -1 && ((_a = import_lodash.default.get(queryParams, ["include", existIncludeIndex, "attributes", "include"])) == null ? void 0 : _a.length) === 0) {
|
|
271
325
|
return;
|
|
272
326
|
}
|
|
273
|
-
if (existIncludeIndex
|
|
327
|
+
if (existIncludeIndex === -1) {
|
|
274
328
|
queryParams["include"].push({
|
|
275
329
|
association: appendAssociation,
|
|
276
330
|
options: appendWithOptions.options || {}
|
|
@@ -282,14 +336,14 @@ const _OptionsParser = class _OptionsParser {
|
|
|
282
336
|
include: []
|
|
283
337
|
// all fields are output by default
|
|
284
338
|
};
|
|
285
|
-
if (appendFields.length
|
|
339
|
+
if (appendFields.length === 2) {
|
|
286
340
|
if (!Array.isArray(attributes)) {
|
|
287
341
|
attributes = [];
|
|
288
342
|
}
|
|
289
343
|
const attributeName = appendFields[1];
|
|
290
344
|
attributes.push(attributeName);
|
|
291
345
|
} else {
|
|
292
|
-
if (Array.isArray(attributes) && attributes.length
|
|
346
|
+
if (Array.isArray(attributes) && attributes.length === 0) {
|
|
293
347
|
attributes = {
|
|
294
348
|
include: []
|
|
295
349
|
};
|
|
@@ -301,7 +355,7 @@ const _OptionsParser = class _OptionsParser {
|
|
|
301
355
|
};
|
|
302
356
|
} else {
|
|
303
357
|
const existInclude = queryParams["include"][existIncludeIndex];
|
|
304
|
-
if (existInclude.attributes && Array.isArray(existInclude.attributes) && existInclude.attributes.length
|
|
358
|
+
if (existInclude.attributes && Array.isArray(existInclude.attributes) && existInclude.attributes.length === 0) {
|
|
305
359
|
existInclude.attributes = {
|
|
306
360
|
include: []
|
|
307
361
|
};
|
|
@@ -62,7 +62,7 @@ function belongsToManyAssociations(instance) {
|
|
|
62
62
|
const associations = modelAssociations(instance);
|
|
63
63
|
return Object.entries(associations).filter((entry) => {
|
|
64
64
|
const [key, association] = entry;
|
|
65
|
-
return association.associationType
|
|
65
|
+
return association.associationType === "BelongsToMany";
|
|
66
66
|
}).map((association) => {
|
|
67
67
|
return association[1];
|
|
68
68
|
});
|
|
@@ -155,12 +155,12 @@ function isReverseAssociationPair(a, b) {
|
|
|
155
155
|
const typeSet = /* @__PURE__ */ new Set();
|
|
156
156
|
typeSet.add(a.associationType);
|
|
157
157
|
typeSet.add(b.associationType);
|
|
158
|
-
if (typeSet.size
|
|
158
|
+
if (typeSet.size === 1 && typeSet.has("BelongsToMany")) {
|
|
159
159
|
return a.through.tableName === b.through.tableName && a.target.name === b.source.name && b.target.name === a.source.name && a.foreignKey === b.otherKey && a.sourceKey === b.targetKey && a.otherKey === b.foreignKey && a.targetKey === b.sourceKey;
|
|
160
160
|
}
|
|
161
161
|
if (typeSet.has("HasOne") && typeSet.has("BelongsTo") || typeSet.has("HasMany") && typeSet.has("BelongsTo")) {
|
|
162
|
-
const sourceAssoc = a.associationType
|
|
163
|
-
const targetAssoc = sourceAssoc
|
|
162
|
+
const sourceAssoc = a.associationType === "BelongsTo" ? b : a;
|
|
163
|
+
const targetAssoc = sourceAssoc === a ? b : a;
|
|
164
164
|
return sourceAssoc.source.name === targetAssoc.target.name && sourceAssoc.target.name === targetAssoc.source.name && sourceAssoc.foreignKey === targetAssoc.foreignKey && sourceAssoc.sourceKey === targetAssoc.targetKey;
|
|
165
165
|
}
|
|
166
166
|
return false;
|
|
@@ -204,7 +204,10 @@ async function updateSingleAssociation(model, key, value, options = {}) {
|
|
|
204
204
|
return true;
|
|
205
205
|
}, "removeAssociation");
|
|
206
206
|
if (isUndefinedOrNull(value)) {
|
|
207
|
-
|
|
207
|
+
if (!isUndefinedOrNull(await model[association.accessors.get]())) {
|
|
208
|
+
return await removeAssociation();
|
|
209
|
+
}
|
|
210
|
+
return true;
|
|
208
211
|
}
|
|
209
212
|
if (association.associationType === "HasOne" && !model.get(association.sourceKeyAttribute)) {
|
|
210
213
|
throw new Error(`The source key ${association.sourceKeyAttribute} is not set in ${model.constructor.name}`);
|
|
@@ -244,7 +247,7 @@ async function updateSingleAssociation(model, key, value, options = {}) {
|
|
|
244
247
|
transaction
|
|
245
248
|
});
|
|
246
249
|
if (instance2) {
|
|
247
|
-
await model[setAccessor](instance2, { context, transaction });
|
|
250
|
+
await model[setAccessor](instance2, { context, transaction, hooks: false });
|
|
248
251
|
if (!recursive) {
|
|
249
252
|
return;
|
|
250
253
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@tachybase/database",
|
|
3
|
-
"version": "0.23.
|
|
3
|
+
"version": "0.23.35",
|
|
4
4
|
"description": "",
|
|
5
5
|
"license": "Apache-2.0",
|
|
6
6
|
"main": "./lib/index.js",
|
|
@@ -24,8 +24,8 @@
|
|
|
24
24
|
"semver": "^7.6.3",
|
|
25
25
|
"sequelize": "^6.37.5",
|
|
26
26
|
"umzug": "^3.8.2",
|
|
27
|
-
"@tachybase/logger": "0.23.
|
|
28
|
-
"@tachybase/utils": "0.23.
|
|
27
|
+
"@tachybase/logger": "0.23.35",
|
|
28
|
+
"@tachybase/utils": "0.23.35"
|
|
29
29
|
},
|
|
30
30
|
"devDependencies": {
|
|
31
31
|
"@types/flat": "^5.0.5",
|