@strapi/database 5.50.0 → 5.50.1
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/dist/entity-manager/index.d.ts.map +1 -1
- package/dist/entity-manager/index.js +122 -3
- package/dist/entity-manager/index.js.map +1 -1
- package/dist/entity-manager/index.mjs +123 -4
- package/dist/entity-manager/index.mjs.map +1 -1
- package/dist/entity-manager/regular-relations.js +1 -1
- package/dist/entity-manager/regular-relations.js.map +1 -1
- package/dist/entity-manager/regular-relations.mjs +1 -1
- package/dist/entity-manager/regular-relations.mjs.map +1 -1
- package/dist/entity-manager/relations-orderer.js +4 -4
- package/dist/entity-manager/relations-orderer.js.map +1 -1
- package/dist/entity-manager/relations-orderer.mjs +4 -4
- package/dist/entity-manager/relations-orderer.mjs.map +1 -1
- package/dist/query/helpers/order-by.js +1 -1
- package/dist/query/helpers/order-by.js.map +1 -1
- package/dist/query/helpers/order-by.mjs +1 -1
- package/dist/query/helpers/order-by.mjs.map +1 -1
- package/dist/query/query-builder.d.ts.map +1 -1
- package/dist/query/query-builder.js +3 -3
- package/dist/query/query-builder.js.map +1 -1
- package/dist/query/query-builder.mjs +3 -3
- package/dist/query/query-builder.mjs.map +1 -1
- package/package.json +5 -5
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { castArray, pick, has, isNull, isEmpty, compact, differenceWith,
|
|
1
|
+
import { castArray, pick, has, isNull, isEmpty, compact, differenceWith, uniqBy, difference, map, isNil, isPlainObject, isArray, isString, isNumber, isUndefined, isObject, uniqWith, isEqual, isInteger } from 'lodash/fp';
|
|
2
2
|
import { isScalarAttribute, isRelationalAttribute } from '../utils/types.mjs';
|
|
3
3
|
import { createField } from '../fields/index.mjs';
|
|
4
4
|
import createQueryBuilder from '../query/query-builder.mjs';
|
|
@@ -900,7 +900,126 @@ const createEntityManager = (db)=>{
|
|
|
900
900
|
if (isPartialUpdate) {
|
|
901
901
|
if (isAnyToOne(attribute)) ;
|
|
902
902
|
relIdsToaddOrMove = toIds(cleanRelationData.connect);
|
|
903
|
-
|
|
903
|
+
// Use id-only comparison so a disconnect item whose id also appears in
|
|
904
|
+
// the connect array is correctly excluded from deletion (deep-equality
|
|
905
|
+
// fails because connect items carry extra fields like `position`).
|
|
906
|
+
const relIdsToDelete = toIds(differenceWith((a, b)=>a.id === b.id, cleanRelationData.disconnect, cleanRelationData.connect ?? []));
|
|
907
|
+
// When a connect item's position.before/after references an id that is
|
|
908
|
+
// about to be deleted (relIdsToDelete), the referenced row won't exist by
|
|
909
|
+
// the time the adjacentRelations query runs below, causing sortConnectArray
|
|
910
|
+
// to throw. Rewrite such a position to point at the nearest surviving
|
|
911
|
+
// neighbor in the relation's current order, so the item lands where the
|
|
912
|
+
// deleted relation used to be instead of always falling back to the end.
|
|
913
|
+
const idKey = (value)=>String(value);
|
|
914
|
+
const deletedIds = new Set(relIdsToDelete.map(idKey));
|
|
915
|
+
let resolvedConnect = cleanRelationData.connect ?? [];
|
|
916
|
+
if (hasOrderColumn(attribute) && !isEmpty(relIdsToDelete) && resolvedConnect.some((item)=>{
|
|
917
|
+
const adjacentId = item.position?.before ?? item.position?.after;
|
|
918
|
+
return adjacentId != null && deletedIds.has(idKey(adjacentId));
|
|
919
|
+
})) {
|
|
920
|
+
const currentOrder = await this.createQueryBuilder(joinTable.name).select([
|
|
921
|
+
inverseJoinColumn.name,
|
|
922
|
+
orderColumnName
|
|
923
|
+
]).where({
|
|
924
|
+
[joinColumn.name]: id
|
|
925
|
+
}).where(joinTable.on || {}).orderBy(orderColumnName).transacting(trx).execute();
|
|
926
|
+
const orderedIds = currentOrder.map((rel)=>rel[inverseJoinColumn.name]);
|
|
927
|
+
const orderedIdKeys = orderedIds.map(idKey);
|
|
928
|
+
const connectIds = new Set(resolvedConnect.map((item)=>idKey(item.id)));
|
|
929
|
+
const deletedIdsInCurrentOrder = new Set(orderedIds.map(idKey).filter((orderedId)=>deletedIds.has(orderedId)));
|
|
930
|
+
// A neighbor is only a valid fallback target if it survives the delete
|
|
931
|
+
// and isn't being moved by this connect payload.
|
|
932
|
+
const findSurvivingNeighbor = (targetId, direction)=>{
|
|
933
|
+
let index = orderedIdKeys.indexOf(idKey(targetId));
|
|
934
|
+
while(index !== -1){
|
|
935
|
+
index += direction;
|
|
936
|
+
const candidate = orderedIds[index];
|
|
937
|
+
if (candidate === undefined) {
|
|
938
|
+
return undefined;
|
|
939
|
+
}
|
|
940
|
+
const candidateKey = idKey(candidate);
|
|
941
|
+
if (!deletedIds.has(candidateKey) && !connectIds.has(candidateKey)) {
|
|
942
|
+
return candidate;
|
|
943
|
+
}
|
|
944
|
+
}
|
|
945
|
+
return undefined;
|
|
946
|
+
};
|
|
947
|
+
const positionByConnectId = new Map();
|
|
948
|
+
const connectGroups = new Map();
|
|
949
|
+
const getConnectGroup = (targetId)=>{
|
|
950
|
+
const targetKey = idKey(targetId);
|
|
951
|
+
let group = connectGroups.get(targetKey);
|
|
952
|
+
if (!group) {
|
|
953
|
+
group = {
|
|
954
|
+
targetId,
|
|
955
|
+
before: [],
|
|
956
|
+
after: []
|
|
957
|
+
};
|
|
958
|
+
connectGroups.set(targetKey, group);
|
|
959
|
+
}
|
|
960
|
+
return group;
|
|
961
|
+
};
|
|
962
|
+
resolvedConnect.forEach((item)=>{
|
|
963
|
+
const { before, after } = item.position ?? {};
|
|
964
|
+
const adjacentId = before ?? after;
|
|
965
|
+
if (adjacentId == null || !deletedIds.has(idKey(adjacentId)) || !deletedIdsInCurrentOrder.has(idKey(adjacentId))) {
|
|
966
|
+
return;
|
|
967
|
+
}
|
|
968
|
+
const group = getConnectGroup(adjacentId);
|
|
969
|
+
if (before) {
|
|
970
|
+
group.before.push(item);
|
|
971
|
+
} else {
|
|
972
|
+
group.after.push(item);
|
|
973
|
+
}
|
|
974
|
+
});
|
|
975
|
+
connectGroups.forEach(({ targetId, before, after })=>{
|
|
976
|
+
const previousNeighbor = findSurvivingNeighbor(targetId, -1);
|
|
977
|
+
const nextNeighbor = findSurvivingNeighbor(targetId, 1);
|
|
978
|
+
let previousPositionId = previousNeighbor;
|
|
979
|
+
before.forEach((item)=>{
|
|
980
|
+
if (previousPositionId !== undefined) {
|
|
981
|
+
positionByConnectId.set(item.id, {
|
|
982
|
+
after: previousPositionId
|
|
983
|
+
});
|
|
984
|
+
} else if (nextNeighbor !== undefined) {
|
|
985
|
+
positionByConnectId.set(item.id, {
|
|
986
|
+
before: nextNeighbor
|
|
987
|
+
});
|
|
988
|
+
} else {
|
|
989
|
+
positionByConnectId.set(item.id, {
|
|
990
|
+
start: true
|
|
991
|
+
});
|
|
992
|
+
}
|
|
993
|
+
previousPositionId = item.id;
|
|
994
|
+
});
|
|
995
|
+
after.forEach((item)=>{
|
|
996
|
+
if (previousPositionId !== undefined) {
|
|
997
|
+
positionByConnectId.set(item.id, {
|
|
998
|
+
after: previousPositionId
|
|
999
|
+
});
|
|
1000
|
+
} else if (nextNeighbor !== undefined) {
|
|
1001
|
+
positionByConnectId.set(item.id, {
|
|
1002
|
+
before: nextNeighbor
|
|
1003
|
+
});
|
|
1004
|
+
} else {
|
|
1005
|
+
positionByConnectId.set(item.id, {
|
|
1006
|
+
start: true
|
|
1007
|
+
});
|
|
1008
|
+
}
|
|
1009
|
+
previousPositionId = item.id;
|
|
1010
|
+
});
|
|
1011
|
+
});
|
|
1012
|
+
resolvedConnect = resolvedConnect.map((item)=>{
|
|
1013
|
+
const position = positionByConnectId.get(item.id);
|
|
1014
|
+
if (position) {
|
|
1015
|
+
return {
|
|
1016
|
+
...item,
|
|
1017
|
+
position
|
|
1018
|
+
};
|
|
1019
|
+
}
|
|
1020
|
+
return item;
|
|
1021
|
+
});
|
|
1022
|
+
}
|
|
904
1023
|
if (!isEmpty(relIdsToDelete)) {
|
|
905
1024
|
await deleteRelations({
|
|
906
1025
|
id,
|
|
@@ -937,7 +1056,7 @@ const createEntityManager = (db)=>{
|
|
|
937
1056
|
{
|
|
938
1057
|
[joinColumn.name]: id,
|
|
939
1058
|
[inverseJoinColumn.name]: {
|
|
940
|
-
$in: compact(
|
|
1059
|
+
$in: compact(resolvedConnect.map((r)=>r.position?.after || r.position?.before))
|
|
941
1060
|
}
|
|
942
1061
|
},
|
|
943
1062
|
{
|
|
@@ -948,7 +1067,7 @@ const createEntityManager = (db)=>{
|
|
|
948
1067
|
}
|
|
949
1068
|
]
|
|
950
1069
|
}).where(joinTable.on || {}).transacting(trx).execute();
|
|
951
|
-
const orderMap = relationsOrderer(adjacentRelations, inverseJoinColumn.name, joinTable.orderColumnName, cleanRelationData.options?.strict).connect(
|
|
1070
|
+
const orderMap = relationsOrderer(adjacentRelations, inverseJoinColumn.name, joinTable.orderColumnName, cleanRelationData.options?.strict).connect(resolvedConnect).getOrderMap();
|
|
952
1071
|
insert.forEach((row)=>{
|
|
953
1072
|
row[orderColumnName] = orderMap[row[inverseJoinColumn.name]];
|
|
954
1073
|
});
|