@nymphjs/tilmeld 1.0.0-beta.122 → 1.0.0-beta.124

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/src/Group.ts CHANGED
@@ -1,13 +1,13 @@
1
1
  import crypto from 'node:crypto';
2
2
  import {
3
- type Nymph,
4
3
  type EntityData,
5
4
  type EntityJson,
6
5
  type EntityPatch,
7
6
  type Options,
8
7
  type Selector,
9
8
  type SerializedEntityData,
10
- MethodFailedError,
9
+ transaction,
10
+ transactional,
11
11
  } from '@nymphjs/nymph';
12
12
  import { nanoid } from '@nymphjs/guid';
13
13
  import { difference, xor } from 'lodash-es';
@@ -326,7 +326,7 @@ export default class Group extends AbleObject<GroupData> {
326
326
  return uniques;
327
327
  }
328
328
 
329
- public $getAvatar() {
329
+ public $getAvatar(): string {
330
330
  if (this.$data.avatar != null && this.$data.avatar !== '') {
331
331
  return this.$data.avatar;
332
332
  }
@@ -493,7 +493,7 @@ export default class Group extends AbleObject<GroupData> {
493
493
  }
494
494
 
495
495
  /**
496
- * Check whether the group is a descendant of a group.
496
+ * Check whether the group is a descendant of the given group.
497
497
  *
498
498
  * @param group The group, or the group's GUID.
499
499
  * @returns True or false.
@@ -531,7 +531,7 @@ export default class Group extends AbleObject<GroupData> {
531
531
  *
532
532
  * @returns An array of groups.
533
533
  */
534
- public async $getChildren() {
534
+ public async $getChildren(): Promise<(Group & GroupData)[]> {
535
535
  const tilmeld = enforceTilmeld(this);
536
536
  return await this.$nymph.getEntities(
537
537
  { class: tilmeld.Group },
@@ -547,10 +547,12 @@ export default class Group extends AbleObject<GroupData> {
547
547
  * Gets an array of the group's descendant groups.
548
548
  *
549
549
  * @param andSelf Include this group in the returned array.
550
+ * @param andDisabled Include disabled groups.
550
551
  * @returns An array of groups.
551
552
  */
552
553
  public async $getDescendants(
553
554
  andSelf = false,
555
+ andDisabled = false,
554
556
  ): Promise<(Group & GroupData)[]> {
555
557
  const tilmeld = enforceTilmeld(this);
556
558
  let groups: (Group & GroupData)[] = [];
@@ -558,7 +560,7 @@ export default class Group extends AbleObject<GroupData> {
558
560
  { class: tilmeld.Group },
559
561
  {
560
562
  type: '&',
561
- equal: ['enabled', true],
563
+ ...(andDisabled ? {} : { equal: ['enabled', true] }),
562
564
  ref: ['parent', this],
563
565
  },
564
566
  );
@@ -582,7 +584,7 @@ export default class Group extends AbleObject<GroupData> {
582
584
  *
583
585
  * @returns The level of the group.
584
586
  */
585
- public async $getLevel() {
587
+ public async $getLevel(): Promise<number> {
586
588
  const tilmeld = enforceTilmeld(this);
587
589
  let group = await tilmeld.Group.factory(this.guid ?? undefined);
588
590
  let parent = group.parent;
@@ -598,7 +600,7 @@ export default class Group extends AbleObject<GroupData> {
598
600
  }
599
601
 
600
602
  /**
601
- * Gets an array of users in the group.
603
+ * Gets an array of enabled users in the group.
602
604
  *
603
605
  * @param descendants Include users in all descendant groups too.
604
606
  * @param limit The limit for the query.
@@ -621,10 +623,7 @@ export default class Group extends AbleObject<GroupData> {
621
623
  limit,
622
624
  offset,
623
625
  },
624
- {
625
- type: '&',
626
- equal: ['enabled', true],
627
- },
626
+ { type: '&', equal: ['enabled', true] },
628
627
  {
629
628
  type: '|',
630
629
  ref: [
@@ -1011,61 +1010,43 @@ export default class Group extends AbleObject<GroupData> {
1011
1010
  }
1012
1011
  }
1013
1012
 
1014
- const transaction = 'tilmeld-save-group-' + (this.guid || nanoid());
1015
- const nymph = this.$nymph;
1016
- const tnymph = await nymph.startTransaction(transaction);
1017
- this.$setNymph(tnymph);
1018
- tilmeld = enforceTilmeld(this);
1019
-
1020
1013
  let preGuid = this.guid;
1021
1014
  let preCdate = this.cdate;
1022
1015
  let preMdate = this.mdate;
1023
-
1024
- try {
1025
- for (let callback of (this.constructor as typeof Group)
1026
- .beforeSaveCallbacks) {
1027
- if (callback) {
1028
- await callback(this);
1016
+ return await transaction(
1017
+ this.$nymph,
1018
+ 'tilmeld-save-group-' + (this.guid || nanoid()),
1019
+ async (nymph) => {
1020
+ this.$setNymph(nymph);
1021
+
1022
+ for (let callback of (this.constructor as typeof Group)
1023
+ .beforeSaveCallbacks) {
1024
+ if (callback) {
1025
+ await callback(this);
1026
+ }
1029
1027
  }
1030
- }
1031
-
1032
- await super.$save();
1033
1028
 
1034
- this.$originalGroupname = this.$data.groupname;
1029
+ await super.$save();
1035
1030
 
1036
- for (let callback of (this.constructor as typeof Group)
1037
- .afterSaveCallbacks) {
1038
- if (callback) {
1039
- await callback(this);
1031
+ for (let callback of (this.constructor as typeof Group)
1032
+ .afterSaveCallbacks) {
1033
+ if (callback) {
1034
+ await callback(this);
1035
+ }
1040
1036
  }
1041
- }
1042
- } catch (e: any) {
1043
- try {
1044
- await tnymph.rollback(transaction);
1045
- } catch (e: any) {
1046
- nymph.config.debugError(
1047
- 'tilmeld',
1048
- `Rollback of transaction ${transaction} failed, reason: ${e.message}`,
1049
- );
1050
- }
1051
- this.guid = preGuid;
1052
- this.cdate = preCdate;
1053
- this.mdate = preMdate;
1054
- this.$setNymph(nymph);
1055
- throw e;
1056
- }
1057
-
1058
- let committed = false;
1059
- try {
1060
- committed = await tnymph.commit(transaction);
1061
- } catch (e: any) {
1062
- committed = false;
1063
- }
1064
- this.$setNymph(nymph);
1065
-
1066
- if (!committed) {
1067
- throw new MethodFailedError('Transaction could not be committed.');
1068
- }
1037
+ },
1038
+ async (nymph, committed) => {
1039
+ this.$setNymph(nymph);
1040
+
1041
+ if (committed) {
1042
+ this.$originalGroupname = this.$data.groupname;
1043
+ } else {
1044
+ this.guid = preGuid;
1045
+ this.cdate = preCdate;
1046
+ this.mdate = preMdate;
1047
+ }
1048
+ },
1049
+ );
1069
1050
  }
1070
1051
 
1071
1052
  /*
@@ -1084,8 +1065,11 @@ export default class Group extends AbleObject<GroupData> {
1084
1065
  return false;
1085
1066
  }
1086
1067
 
1068
+ @transactional
1087
1069
  public async $delete() {
1088
1070
  let tilmeld = enforceTilmeld(this);
1071
+ const User = this.$nymph.getEntityClass(UserClass);
1072
+
1089
1073
  if (!this.$skipAcWhenDeleting && !tilmeld.gatekeeper('tilmeld/admin')) {
1090
1074
  throw new AccessControlError(
1091
1075
  "You don't have the authority to delete groups.",
@@ -1097,123 +1081,64 @@ export default class Group extends AbleObject<GroupData> {
1097
1081
  );
1098
1082
  }
1099
1083
 
1100
- const transaction = 'tilmeld-delete-group-' + this.guid;
1101
- const nymph = this.$nymph;
1102
- const tnymph = await nymph.startTransaction(transaction);
1103
- this.$setNymph(tnymph);
1104
- tilmeld = enforceTilmeld(this);
1105
- const User = tnymph.getEntityClass(UserClass);
1106
-
1107
- try {
1108
- for (let callback of (this.constructor as typeof Group)
1109
- .beforeDeleteCallbacks) {
1110
- if (callback) {
1111
- await callback(this);
1112
- }
1113
- }
1114
-
1115
- // Delete descendants.
1116
- const descendants = await this.$getDescendants();
1117
- if (descendants.length) {
1118
- for (let curGroup of descendants) {
1119
- try {
1120
- if (this.$skipAcWhenDeleting) {
1121
- await curGroup.$deleteSkipAC();
1122
- } else {
1123
- await curGroup.$delete();
1124
- }
1125
- } catch (e: any) {
1126
- await tnymph.rollback(transaction);
1127
- this.$setNymph(nymph);
1128
- throw e;
1129
- }
1130
- }
1084
+ for (let callback of (this.constructor as typeof Group)
1085
+ .beforeDeleteCallbacks) {
1086
+ if (callback) {
1087
+ await callback(this);
1131
1088
  }
1089
+ }
1132
1090
 
1133
- // Remove users from this primary group.
1134
- const primaryUsers = await tnymph.getEntities(
1135
- {
1136
- class: User,
1137
- skipAc: true,
1138
- },
1139
- {
1140
- type: '&',
1141
- ref: ['group', this],
1142
- },
1143
- );
1144
- for (let user of primaryUsers) {
1145
- delete user.group;
1146
- try {
1147
- if (this.$skipAcWhenDeleting) {
1148
- await user.$saveSkipAC();
1149
- } else {
1150
- await user.$save();
1151
- }
1152
- } catch (e: any) {
1153
- await tnymph.rollback(transaction);
1154
- this.$setNymph(nymph);
1155
- throw e;
1091
+ // Delete children.
1092
+ const children = await this.$nymph.getEntities(
1093
+ { class: tilmeld.Group, skipAc: true },
1094
+ { type: '&', ref: ['parent', this] },
1095
+ );
1096
+ if (children.length) {
1097
+ for (let curGroup of children) {
1098
+ if (this.$skipAcWhenDeleting) {
1099
+ await curGroup.$deleteSkipAC();
1100
+ } else {
1101
+ await curGroup.$delete();
1156
1102
  }
1157
1103
  }
1104
+ }
1158
1105
 
1159
- // Remove users from this secondary group.
1160
- const secondaryUsers = await tnymph.getEntities(
1161
- {
1162
- class: User,
1163
- skipAc: true,
1164
- },
1165
- {
1166
- type: '&',
1167
- ref: ['groups', this],
1168
- },
1169
- );
1170
- for (let user of secondaryUsers) {
1171
- user.$delGroup(this);
1172
- try {
1173
- if (this.$skipAcWhenDeleting) {
1174
- await user.$saveSkipAC();
1175
- } else {
1176
- await user.$save();
1177
- }
1178
- } catch (e: any) {
1179
- await tnymph.rollback(transaction);
1180
- this.$setNymph(nymph);
1181
- throw e;
1182
- }
1106
+ // Remove users from this primary group.
1107
+ const primaryUsers = await this.$nymph.getEntities(
1108
+ { class: User, skipAc: true },
1109
+ { type: '&', ref: ['group', this] },
1110
+ );
1111
+ for (let user of primaryUsers) {
1112
+ delete user.group;
1113
+ if (this.$skipAcWhenDeleting) {
1114
+ await user.$saveSkipAC();
1115
+ } else {
1116
+ await user.$save();
1183
1117
  }
1118
+ }
1184
1119
 
1185
- // Delete the group.
1186
- await super.$delete();
1187
-
1188
- for (let callback of (this.constructor as typeof Group)
1189
- .afterDeleteCallbacks) {
1190
- if (callback) {
1191
- await callback(this);
1192
- }
1193
- }
1194
- } catch (e: any) {
1195
- try {
1196
- await tnymph.rollback(transaction);
1197
- } catch (e: any) {
1198
- nymph.config.debugError(
1199
- 'tilmeld',
1200
- `Rollback of transaction ${transaction} failed, reason: ${e.message}`,
1201
- );
1120
+ // Remove users from this secondary group.
1121
+ const secondaryUsers = await this.$nymph.getEntities(
1122
+ { class: User, skipAc: true },
1123
+ { type: '&', ref: ['groups', this] },
1124
+ );
1125
+ for (let user of secondaryUsers) {
1126
+ user.$delGroup(this);
1127
+ if (this.$skipAcWhenDeleting) {
1128
+ await user.$saveSkipAC();
1129
+ } else {
1130
+ await user.$save();
1202
1131
  }
1203
- this.$setNymph(nymph);
1204
- throw e;
1205
1132
  }
1206
1133
 
1207
- let committed = false;
1208
- try {
1209
- committed = await tnymph.commit(transaction);
1210
- } catch (e: any) {
1211
- committed = false;
1212
- }
1213
- this.$setNymph(nymph);
1134
+ // Delete the group.
1135
+ await super.$delete();
1214
1136
 
1215
- if (!committed) {
1216
- throw new MethodFailedError('Transaction could not be committed.');
1137
+ for (let callback of (this.constructor as typeof Group)
1138
+ .afterDeleteCallbacks) {
1139
+ if (callback) {
1140
+ await callback(this);
1141
+ }
1217
1142
  }
1218
1143
  }
1219
1144
 
package/src/Tilmeld.ts CHANGED
@@ -230,8 +230,10 @@ export default class Tilmeld implements TilmeldInterface {
230
230
  options.class?.factorySync() instanceof User) || // The use is searching for a user and searching is disabled.
231
231
  (!tilmeld.config.enableGroupSearch &&
232
232
  options.class?.factorySync() instanceof Group)) && // Or the same, but for a group.
233
- (selectors[0] == null || // No selector specified.
233
+ (selectors.length > 1 || // There's more than one selector.
234
+ selectors[0] == null || // Or no selector specified.
234
235
  selectors[0].type !== '&' || // Or the type is not and.
236
+ Object.keys(selectors[0]).length > 2 || // Or there's more than one clause.
235
237
  (!('guid' in selectors[0]) && !('equal' in selectors[0])) || // Or they're searching for something other than guid or equal.
236
238
  ('guid' in selectors[0] &&
237
239
  (!selectors[0].guid?.length ||
@@ -684,20 +686,12 @@ export default class Tilmeld implements TilmeldInterface {
684
686
  subSelectors.push({
685
687
  type: '&',
686
688
  gte: [['acGroup', TilmeldAccessLevels.READ_ACCESS]],
687
- selector: [
688
- {
689
- type: '|',
690
- ref: groupRefs,
691
- },
692
- ],
689
+ selector: [{ type: '|', ref: groupRefs }],
693
690
  });
694
691
  }
695
692
  // All the acRead, acWrite, and acFull contains.
696
693
  if (acContains.length) {
697
- subSelectors.push({
698
- type: '|',
699
- contain: acContains,
700
- });
694
+ subSelectors.push({ type: '|', contain: acContains });
701
695
  }
702
696
  const selector: FormattedSelector = { type: '|' };
703
697
  if (
@@ -1044,10 +1038,7 @@ export default class Tilmeld implements TilmeldInterface {
1044
1038
 
1045
1039
  const user = await this.nymph.getEntity(
1046
1040
  { class: this.User },
1047
- {
1048
- type: '&',
1049
- guid: guid,
1050
- },
1041
+ { type: '&', guid },
1051
1042
  );
1052
1043
  if (!user || !user.guid) {
1053
1044
  return null;
@@ -1332,24 +1323,4 @@ export default class Tilmeld implements TilmeldInterface {
1332
1323
  await this.authenticate(false, true);
1333
1324
  }
1334
1325
  }
1335
-
1336
- // /**
1337
- // * Sort an array of groups hierarchically.
1338
- // *
1339
- // * An additional property of the groups can be used to sort them under their
1340
- // * parents.
1341
- // *
1342
- // * @param array The array of groups.
1343
- // * @param property The name of the property to sort groups by. Undefined for no additional sorting.
1344
- // * @param caseSensitive Sort case sensitively.
1345
- // * @param reverse Reverse the sort order.
1346
- // */
1347
- // public static groupSort(
1348
- // array: any[],
1349
- // property?: string,
1350
- // caseSensitive = false,
1351
- // reverse = false
1352
- // ) {
1353
- // hsort(array, property, 'parent', caseSensitive, reverse);
1354
- // }
1355
1326
  }