@falkenslab/moodle-driver 0.4.1 → 0.5.0

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 (182) hide show
  1. package/README.md +3 -2
  2. package/dist/areas/activities/build.d.ts +47 -10
  3. package/dist/areas/activities/build.js +157 -24
  4. package/dist/areas/activities/build.js.map +1 -1
  5. package/dist/areas/activities/conditions.d.ts +77 -0
  6. package/dist/areas/activities/conditions.js +216 -0
  7. package/dist/areas/activities/conditions.js.map +1 -0
  8. package/dist/areas/activities/content.d.ts +3 -0
  9. package/dist/areas/activities/content.js +1 -0
  10. package/dist/areas/activities/content.js.map +1 -1
  11. package/dist/areas/assignments/grader.d.ts +32 -0
  12. package/dist/areas/assignments/grader.js +66 -2
  13. package/dist/areas/assignments/grader.js.map +1 -1
  14. package/dist/areas/assignments/grading.d.ts +69 -6
  15. package/dist/areas/assignments/grading.js +173 -13
  16. package/dist/areas/assignments/grading.js.map +1 -1
  17. package/dist/areas/assignments/student.d.ts +14 -0
  18. package/dist/areas/assignments/student.js +43 -2
  19. package/dist/areas/assignments/student.js.map +1 -1
  20. package/dist/areas/backup/backup.d.ts +86 -0
  21. package/dist/areas/backup/backup.js +368 -0
  22. package/dist/areas/backup/backup.js.map +1 -0
  23. package/dist/areas/calendar/calendar.d.ts +27 -0
  24. package/dist/areas/calendar/calendar.js +115 -9
  25. package/dist/areas/calendar/calendar.js.map +1 -1
  26. package/dist/areas/completion/completion.d.ts +3 -0
  27. package/dist/areas/completion/completion.js.map +1 -1
  28. package/dist/areas/courses/list.d.ts +2 -0
  29. package/dist/areas/courses/list.js.map +1 -1
  30. package/dist/areas/courses/reset.d.ts +51 -0
  31. package/dist/areas/courses/reset.js +123 -0
  32. package/dist/areas/courses/reset.js.map +1 -0
  33. package/dist/areas/courses/state.d.ts +17 -0
  34. package/dist/areas/courses/state.js +37 -6
  35. package/dist/areas/courses/state.js.map +1 -1
  36. package/dist/areas/courses/structure.d.ts +14 -2
  37. package/dist/areas/courses/structure.js +11 -5
  38. package/dist/areas/courses/structure.js.map +1 -1
  39. package/dist/areas/forums/discussions.d.ts +8 -0
  40. package/dist/areas/forums/discussions.js +10 -0
  41. package/dist/areas/forums/discussions.js.map +1 -1
  42. package/dist/areas/forums/grading.d.ts +49 -0
  43. package/dist/areas/forums/grading.js +125 -0
  44. package/dist/areas/forums/grading.js.map +1 -0
  45. package/dist/areas/forums/posts.d.ts +37 -0
  46. package/dist/areas/forums/posts.js +141 -6
  47. package/dist/areas/forums/posts.js.map +1 -1
  48. package/dist/areas/grades/export.d.ts +38 -0
  49. package/dist/areas/grades/export.js +88 -0
  50. package/dist/areas/grades/export.js.map +1 -0
  51. package/dist/areas/grades/gradebook.d.ts +50 -0
  52. package/dist/areas/grades/gradebook.js +120 -0
  53. package/dist/areas/grades/gradebook.js.map +1 -1
  54. package/dist/areas/grades/singleview.d.ts +39 -0
  55. package/dist/areas/grades/singleview.js +186 -0
  56. package/dist/areas/grades/singleview.js.map +1 -0
  57. package/dist/areas/h5p/h5p.d.ts +2 -0
  58. package/dist/areas/h5p/h5p.js +12 -7
  59. package/dist/areas/h5p/h5p.js.map +1 -1
  60. package/dist/areas/lessons/lessons.d.ts +1 -0
  61. package/dist/areas/lessons/lessons.js.map +1 -1
  62. package/dist/areas/messages/messages.d.ts +32 -0
  63. package/dist/areas/messages/messages.js +44 -2
  64. package/dist/areas/messages/messages.js.map +1 -1
  65. package/dist/areas/participants/enrolments.d.ts +60 -0
  66. package/dist/areas/participants/enrolments.js +218 -0
  67. package/dist/areas/participants/enrolments.js.map +1 -0
  68. package/dist/areas/participants/groups.d.ts +75 -0
  69. package/dist/areas/participants/groups.js +201 -0
  70. package/dist/areas/participants/groups.js.map +1 -0
  71. package/dist/areas/participants/methods.d.ts +56 -0
  72. package/dist/areas/participants/methods.js +154 -0
  73. package/dist/areas/participants/methods.js.map +1 -0
  74. package/dist/areas/participants/participants.d.ts +11 -0
  75. package/dist/areas/participants/participants.js +24 -19
  76. package/dist/areas/participants/participants.js.map +1 -1
  77. package/dist/areas/questions/banks.d.ts +36 -1
  78. package/dist/areas/questions/banks.js +140 -17
  79. package/dist/areas/questions/banks.js.map +1 -1
  80. package/dist/areas/quizzes/attempts.d.ts +2 -0
  81. package/dist/areas/quizzes/attempts.js +9 -0
  82. package/dist/areas/quizzes/attempts.js.map +1 -1
  83. package/dist/areas/quizzes/grading.d.ts +50 -0
  84. package/dist/areas/quizzes/grading.js +131 -0
  85. package/dist/areas/quizzes/grading.js.map +1 -0
  86. package/dist/areas/quizzes/results.d.ts +3 -0
  87. package/dist/areas/quizzes/results.js +2 -1
  88. package/dist/areas/quizzes/results.js.map +1 -1
  89. package/dist/areas/quizzes/structure.d.ts +65 -9
  90. package/dist/areas/quizzes/structure.js +222 -23
  91. package/dist/areas/quizzes/structure.js.map +1 -1
  92. package/dist/areas/ratings/ratings.d.ts +26 -0
  93. package/dist/areas/ratings/ratings.js +108 -0
  94. package/dist/areas/ratings/ratings.js.map +1 -0
  95. package/dist/areas/reports/dates.d.ts +18 -0
  96. package/dist/areas/reports/dates.js +134 -0
  97. package/dist/areas/reports/dates.js.map +1 -0
  98. package/dist/areas/reports/reports.d.ts +143 -0
  99. package/dist/areas/reports/reports.js +267 -0
  100. package/dist/areas/reports/reports.js.map +1 -0
  101. package/dist/areas/scorm/scorm.d.ts +1 -0
  102. package/dist/areas/scorm/scorm.js.map +1 -1
  103. package/dist/areas/site/users.d.ts +7 -1
  104. package/dist/areas/site/users.js +9 -2
  105. package/dist/areas/site/users.js.map +1 -1
  106. package/dist/areas/surveys/choice.d.ts +2 -0
  107. package/dist/areas/surveys/choice.js +6 -3
  108. package/dist/areas/surveys/choice.js.map +1 -1
  109. package/dist/areas/surveys/surveys.d.ts +3 -0
  110. package/dist/areas/surveys/surveys.js +1 -0
  111. package/dist/areas/surveys/surveys.js.map +1 -1
  112. package/dist/areas/workshops/workshops.d.ts +133 -0
  113. package/dist/areas/workshops/workshops.js +335 -0
  114. package/dist/areas/workshops/workshops.js.map +1 -0
  115. package/dist/browser/background.d.ts +43 -0
  116. package/dist/browser/background.js +164 -0
  117. package/dist/browser/background.js.map +1 -0
  118. package/dist/browser/host.d.ts +30 -0
  119. package/dist/browser/host.js +373 -0
  120. package/dist/browser/host.js.map +1 -0
  121. package/dist/browser/manager.d.ts +9 -0
  122. package/dist/browser/manager.js +8 -0
  123. package/dist/browser/manager.js.map +1 -1
  124. package/dist/categories.d.ts +1 -0
  125. package/dist/categories.js +67 -0
  126. package/dist/categories.js.map +1 -1
  127. package/dist/cli/args.d.ts +8 -0
  128. package/dist/cli/args.js +49 -0
  129. package/dist/cli/args.js.map +1 -1
  130. package/dist/cli/background.d.ts +23 -0
  131. package/dist/cli/background.js +128 -0
  132. package/dist/cli/background.js.map +1 -0
  133. package/dist/cli/command.d.ts +66 -0
  134. package/dist/cli/command.js +328 -0
  135. package/dist/cli/command.js.map +1 -0
  136. package/dist/cli/commands.generated.js +2635 -577
  137. package/dist/cli/commands.generated.js.map +1 -1
  138. package/dist/cli/config.d.ts +2 -0
  139. package/dist/cli/config.js +2 -0
  140. package/dist/cli/config.js.map +1 -1
  141. package/dist/cli/main.js +30 -10
  142. package/dist/cli/main.js.map +1 -1
  143. package/dist/cli/run.d.ts +3 -14
  144. package/dist/cli/run.js +9 -185
  145. package/dist/cli/run.js.map +1 -1
  146. package/dist/cli/shell.d.ts +9 -0
  147. package/dist/cli/shell.js +233 -0
  148. package/dist/cli/shell.js.map +1 -0
  149. package/dist/client.d.ts +71 -8
  150. package/dist/client.js +75 -8
  151. package/dist/client.js.map +1 -1
  152. package/dist/core/errors.d.ts +1 -1
  153. package/dist/core/errors.js.map +1 -1
  154. package/dist/core/files.d.ts +5 -0
  155. package/dist/core/files.js +7 -3
  156. package/dist/core/files.js.map +1 -1
  157. package/dist/core/forms.d.ts +33 -3
  158. package/dist/core/forms.js +105 -8
  159. package/dist/core/forms.js.map +1 -1
  160. package/dist/core/http.d.ts +7 -0
  161. package/dist/core/http.js +28 -7
  162. package/dist/core/http.js.map +1 -1
  163. package/dist/core/login.d.ts +3 -0
  164. package/dist/core/login.js +2 -0
  165. package/dist/core/login.js.map +1 -1
  166. package/dist/core/session.d.ts +12 -1
  167. package/dist/core/session.js +12 -1
  168. package/dist/core/session.js.map +1 -1
  169. package/dist/index.d.ts +35 -11
  170. package/dist/index.js +32 -12
  171. package/dist/index.js.map +1 -1
  172. package/dist/internals.d.ts +9 -1
  173. package/dist/internals.js +9 -4
  174. package/dist/internals.js.map +1 -1
  175. package/dist/options.d.ts +2 -0
  176. package/dist/options.js.map +1 -1
  177. package/dist/testing/fakeMoodle.d.ts +9 -2
  178. package/dist/testing/fakeMoodle.js +5 -3
  179. package/dist/testing/fakeMoodle.js.map +1 -1
  180. package/dist/testing/index.d.ts +7 -0
  181. package/dist/testing/index.js.map +1 -1
  182. package/package.json +2 -1
@@ -70,9 +70,46 @@ export const COMMANDS = [
70
70
  ]
71
71
  }
72
72
  },
73
+ {
74
+ "name": "activityReport",
75
+ "description": "A course's activity report: per activity, how many times it was viewed, by how many people, and when last, from the logs (between `from` and `until` when given). Activities nobody viewed come with zero views.",
76
+ "params": [
77
+ {
78
+ "name": "courseId",
79
+ "optional": false,
80
+ "type": "number",
81
+ "value": {
82
+ "kind": "number"
83
+ }
84
+ }
85
+ ],
86
+ "options": {
87
+ "name": "options",
88
+ "optional": true,
89
+ "open": false,
90
+ "fields": [
91
+ {
92
+ "name": "from",
93
+ "optional": true,
94
+ "type": "Date",
95
+ "value": {
96
+ "kind": "date"
97
+ }
98
+ },
99
+ {
100
+ "name": "until",
101
+ "optional": true,
102
+ "type": "Date",
103
+ "value": {
104
+ "kind": "date"
105
+ }
106
+ }
107
+ ]
108
+ }
109
+ },
73
110
  {
74
111
  "name": "activitySettings",
75
- "description": "An activity's settings as its form holds them, without submitting it: its module, name and description, and every field by the name `updateActivity` takes in `settings`. Teachers only.",
112
+ "description": "An activity's settings as its form holds them, without submitting it: its module, name and description, every field by the name `updateActivity` takes in `settings`, the files of a resource, folder or SCORM, and its restrictions and completion in plain terms. Teachers only.",
76
113
  "params": [
77
114
  {
78
115
  "name": "activityId",
@@ -140,6 +177,67 @@ export const COMMANDS = [
140
177
  ]
141
178
  }
142
179
  },
180
+ {
181
+ "name": "addGradeItem",
182
+ "description": "Adds a manual grade item (one graded in the gradebook, not by an activity): out of `maxGrade` (Moodle's default, 100, when left out) or on a scale (`scaleId`), at the course's top level or in `categoryId`, hidden from students when asked. Returns it as the setup shows it.",
183
+ "params": [
184
+ {
185
+ "name": "courseId",
186
+ "optional": false,
187
+ "type": "number",
188
+ "value": {
189
+ "kind": "number"
190
+ }
191
+ }
192
+ ],
193
+ "options": {
194
+ "name": "options",
195
+ "optional": false,
196
+ "open": false,
197
+ "fields": [
198
+ {
199
+ "name": "name",
200
+ "optional": false,
201
+ "type": "string",
202
+ "value": {
203
+ "kind": "string"
204
+ }
205
+ },
206
+ {
207
+ "name": "maxGrade",
208
+ "optional": true,
209
+ "type": "number",
210
+ "value": {
211
+ "kind": "number"
212
+ }
213
+ },
214
+ {
215
+ "name": "scaleId",
216
+ "optional": true,
217
+ "type": "number",
218
+ "value": {
219
+ "kind": "number"
220
+ }
221
+ },
222
+ {
223
+ "name": "categoryId",
224
+ "optional": true,
225
+ "type": "number",
226
+ "value": {
227
+ "kind": "number"
228
+ }
229
+ },
230
+ {
231
+ "name": "hidden",
232
+ "optional": true,
233
+ "type": "boolean",
234
+ "value": {
235
+ "kind": "boolean"
236
+ }
237
+ }
238
+ ]
239
+ }
240
+ },
143
241
  {
144
242
  "name": "addQuestionsToQuiz",
145
243
  "description": "Adds bank questions to a quiz by id, and random questions from a bank category, at the end or on a page, as the edit page's bank actions post them. Returns the quiz's structure afterwards. A quiz already attempted can't change its questions: Moodle refuses, and so does this.",
@@ -185,9 +283,54 @@ export const COMMANDS = [
185
283
  ]
186
284
  }
187
285
  },
286
+ {
287
+ "name": "addQuizSection",
288
+ "description": "Adds a section to a quiz starting at a slot, with its heading and whether its questions are shuffled, as the edit page's \"Add a new section heading\" and its heading and shuffle controls do. A section starts at a page: the slot must be the first of its page (see `setQuizPages`).",
289
+ "params": [
290
+ {
291
+ "name": "activityId",
292
+ "optional": false,
293
+ "type": "number",
294
+ "value": {
295
+ "kind": "number"
296
+ }
297
+ }
298
+ ],
299
+ "options": {
300
+ "name": "options",
301
+ "optional": false,
302
+ "open": false,
303
+ "fields": [
304
+ {
305
+ "name": "firstSlot",
306
+ "optional": false,
307
+ "type": "number",
308
+ "value": {
309
+ "kind": "number"
310
+ }
311
+ },
312
+ {
313
+ "name": "heading",
314
+ "optional": false,
315
+ "type": "string",
316
+ "value": {
317
+ "kind": "string"
318
+ }
319
+ },
320
+ {
321
+ "name": "shuffle",
322
+ "optional": true,
323
+ "type": "boolean",
324
+ "value": {
325
+ "kind": "boolean"
326
+ }
327
+ }
328
+ ]
329
+ }
330
+ },
188
331
  {
189
332
  "name": "addSection",
190
- "description": "Adds a section after another one (at the end without it), named when a name is given.",
333
+ "description": "Adds a section after another one (at the end without it), named when a name is given, with a description (HTML) when `summary` is.",
191
334
  "params": [
192
335
  {
193
336
  "name": "courseId",
@@ -218,10 +361,48 @@ export const COMMANDS = [
218
361
  "value": {
219
362
  "kind": "number"
220
363
  }
364
+ },
365
+ {
366
+ "name": "summary",
367
+ "optional": true,
368
+ "type": "string",
369
+ "value": {
370
+ "kind": "string"
371
+ }
221
372
  }
222
373
  ]
223
374
  }
224
375
  },
376
+ {
377
+ "name": "allocateMarker",
378
+ "description": "Allocates a marker (the user id of someone who can grade; several where the assignment uses several markers per submission) to participants' submissions, as the grading table's \"Allocate marker\" does. Moodle leaves alone submissions past marking (marking completed, in review, ready for release, released).",
379
+ "params": [
380
+ {
381
+ "name": "activityId",
382
+ "optional": false,
383
+ "type": "number",
384
+ "value": {
385
+ "kind": "number"
386
+ }
387
+ },
388
+ {
389
+ "name": "userIds",
390
+ "optional": false,
391
+ "type": "number[]",
392
+ "value": {
393
+ "kind": "numbers"
394
+ }
395
+ },
396
+ {
397
+ "name": "markerId",
398
+ "optional": false,
399
+ "type": "number | number[]",
400
+ "value": {
401
+ "kind": "json"
402
+ }
403
+ }
404
+ ]
405
+ },
225
406
  {
226
407
  "name": "answerChoice",
227
408
  "description": "Answers a choice with one option (several where it allows them) by id, as \"Save my choice\" does; returns the choice afterwards.",
@@ -327,8 +508,8 @@ export const COMMANDS = [
327
508
  }
328
509
  },
329
510
  {
330
- "name": "assignmentSubmissions",
331
- "description": "Every participant's submission to an assignment, with its content unless `includeContent` is false.",
511
+ "name": "assessWorkshopSubmission",
512
+ "description": "Assesses a submission as the person, through the workshop's assessment form (its grading strategy's: accumulative, comments, number of errors or rubric), as \"Assess\" on the submission's page and the form do: a teacher who hasn't assessed it yet gets an assessment of their own, and one already made is changed. `criteria` go in the form's order; `feedback` is the overall feedback for the author (HTML), where the workshop has it on; `fields` sets any other field of the form by name (`weight`…). Returns a sentence of what changed, the assessment's id, and the grade it gives the submission out of the workshop's grade. Throws `WorkshopError` outside the assessment phase, when a criterion's grade isn't one it takes, or when the workshop has no overall feedback; `FormError` when Moodle refuses the form (a criterion left without a grade).",
332
513
  "params": [
333
514
  {
334
515
  "name": "activityId",
@@ -337,47 +518,80 @@ export const COMMANDS = [
337
518
  "value": {
338
519
  "kind": "number"
339
520
  }
521
+ },
522
+ {
523
+ "name": "submissionId",
524
+ "optional": false,
525
+ "type": "number",
526
+ "value": {
527
+ "kind": "number"
528
+ }
340
529
  }
341
530
  ],
342
531
  "options": {
343
532
  "name": "options",
344
- "optional": true,
533
+ "optional": false,
345
534
  "open": false,
346
535
  "fields": [
347
536
  {
348
- "name": "includeContent",
537
+ "name": "criteria",
349
538
  "optional": true,
350
- "type": "boolean",
539
+ "type": "WorkshopCriterion[]",
351
540
  "value": {
352
- "kind": "boolean"
541
+ "kind": "json"
542
+ }
543
+ },
544
+ {
545
+ "name": "feedback",
546
+ "optional": true,
547
+ "type": "string",
548
+ "value": {
549
+ "kind": "string"
550
+ }
551
+ },
552
+ {
553
+ "name": "fields",
554
+ "optional": true,
555
+ "type": "Record<string, FieldValue>",
556
+ "value": {
557
+ "kind": "json"
353
558
  }
354
559
  }
355
560
  ]
356
561
  }
357
562
  },
358
563
  {
359
- "name": "callService",
360
- "description": "Calls one of Moodle's AJAX services as the logged-in person.",
564
+ "name": "assignmentSubmissions",
565
+ "description": "Every participant's submission to an assignment, with the group they submit for (group submissions), and, unless `includeContent` is false, its content, the feedback files they have, its marking workflow state and markers (all from each participant's grading panel).",
361
566
  "params": [
362
567
  {
363
- "name": "methodname",
568
+ "name": "activityId",
364
569
  "optional": false,
365
- "type": "string",
570
+ "type": "number",
366
571
  "value": {
367
- "kind": "string"
572
+ "kind": "number"
368
573
  }
369
574
  }
370
575
  ],
371
576
  "options": {
372
- "name": "args",
373
- "optional": false,
374
- "open": true,
375
- "fields": []
577
+ "name": "options",
578
+ "optional": true,
579
+ "open": false,
580
+ "fields": [
581
+ {
582
+ "name": "includeContent",
583
+ "optional": true,
584
+ "type": "boolean",
585
+ "value": {
586
+ "kind": "boolean"
587
+ }
588
+ }
589
+ ]
376
590
  }
377
591
  },
378
592
  {
379
- "name": "completionReport",
380
- "description": "A course's progress report: every participant's completion of every activity that tracks it, page by page, in one group when given. People come as user id and full name only.",
593
+ "name": "backupCourse",
594
+ "description": "Backs a course up to a `.mbz` file, through Moodle's backup wizard (initial settings, schema, confirmation), and downloads it into `destDir`. Without users' data unless `withUsers`, which needs `moodle/backup:userinfo` (`anonymize` makes their names anonymous). An asynchronous backup is waited for up to `timeoutMs` (ten minutes). Moodle keeps the file in the course's or the person's backup area too.",
381
595
  "params": [
382
596
  {
383
597
  "name": "courseId",
@@ -386,6 +600,14 @@ export const COMMANDS = [
386
600
  "value": {
387
601
  "kind": "number"
388
602
  }
603
+ },
604
+ {
605
+ "name": "destDir",
606
+ "optional": false,
607
+ "type": "string",
608
+ "value": {
609
+ "kind": "string"
610
+ }
389
611
  }
390
612
  ],
391
613
  "options": {
@@ -394,7 +616,23 @@ export const COMMANDS = [
394
616
  "open": false,
395
617
  "fields": [
396
618
  {
397
- "name": "group",
619
+ "name": "withUsers",
620
+ "optional": true,
621
+ "type": "boolean",
622
+ "value": {
623
+ "kind": "boolean"
624
+ }
625
+ },
626
+ {
627
+ "name": "anonymize",
628
+ "optional": true,
629
+ "type": "boolean",
630
+ "value": {
631
+ "kind": "boolean"
632
+ }
633
+ },
634
+ {
635
+ "name": "timeoutMs",
398
636
  "optional": true,
399
637
  "type": "number",
400
638
  "value": {
@@ -405,11 +643,11 @@ export const COMMANDS = [
405
643
  }
406
644
  },
407
645
  {
408
- "name": "conversation",
409
- "description": "A conversation's messages, oldest first, as text, and its members as `conversations()` gives them: everyone but the person, whether they wrote in it or not (the person alone in their own conversation).",
646
+ "name": "calendarEvent",
647
+ "description": "One calendar event by its id, as `upcomingEvents` gives them.",
410
648
  "params": [
411
649
  {
412
- "name": "conversationId",
650
+ "name": "eventId",
413
651
  "optional": false,
414
652
  "type": "number",
415
653
  "value": {
@@ -419,12 +657,160 @@ export const COMMANDS = [
419
657
  ]
420
658
  },
421
659
  {
422
- "name": "conversations",
423
- "description": "The person's conversations, latest first, with their last message as text.",
424
- "params": []
425
- },
426
- {
427
- "name": "courseAbilities",
660
+ "name": "callService",
661
+ "description": "Calls one of Moodle's AJAX services as the logged-in person.",
662
+ "params": [
663
+ {
664
+ "name": "methodname",
665
+ "optional": false,
666
+ "type": "string",
667
+ "value": {
668
+ "kind": "string"
669
+ }
670
+ }
671
+ ],
672
+ "options": {
673
+ "name": "args",
674
+ "optional": false,
675
+ "open": true,
676
+ "fields": []
677
+ }
678
+ },
679
+ {
680
+ "name": "completionReport",
681
+ "description": "A course's progress report: every participant's completion of every activity that tracks it, page by page, in one group when given. People come as user id and full name only.",
682
+ "params": [
683
+ {
684
+ "name": "courseId",
685
+ "optional": false,
686
+ "type": "number",
687
+ "value": {
688
+ "kind": "number"
689
+ }
690
+ }
691
+ ],
692
+ "options": {
693
+ "name": "options",
694
+ "optional": true,
695
+ "open": false,
696
+ "fields": [
697
+ {
698
+ "name": "group",
699
+ "optional": true,
700
+ "type": "number",
701
+ "value": {
702
+ "kind": "number"
703
+ }
704
+ }
705
+ ]
706
+ }
707
+ },
708
+ {
709
+ "name": "conversation",
710
+ "description": "A conversation's messages, oldest first, as text, and its members as `conversations()` gives them: everyone but the person, whether they wrote in it or not (the person alone in their own conversation).",
711
+ "params": [
712
+ {
713
+ "name": "conversationId",
714
+ "optional": false,
715
+ "type": "number",
716
+ "value": {
717
+ "kind": "number"
718
+ }
719
+ }
720
+ ]
721
+ },
722
+ {
723
+ "name": "conversations",
724
+ "description": "The person's conversations, latest first, with their last message as text.",
725
+ "params": []
726
+ },
727
+ {
728
+ "name": "copyCourse",
729
+ "description": "Copies a course into a new one, as Moodle's \"Copy course\" does: its content (and its people's data and enrolments, `withUsers`), under a new full and short name, in a category (the course's unless given), with new dates. Goes through Moodle's copy service, then waits for the copy, which Moodle makes in its scheduled tasks, up to `timeoutMs` (ten minutes). Needs the rights to back up, restore and create courses (`moodle/backup:backupcourse`, `moodle/restore:restorecourse`, `moodle/course:create`); without them, `BackupError` says so.",
730
+ "params": [
731
+ {
732
+ "name": "courseId",
733
+ "optional": false,
734
+ "type": "number",
735
+ "value": {
736
+ "kind": "number"
737
+ }
738
+ }
739
+ ],
740
+ "options": {
741
+ "name": "options",
742
+ "optional": false,
743
+ "open": false,
744
+ "fields": [
745
+ {
746
+ "name": "fullName",
747
+ "optional": false,
748
+ "type": "string",
749
+ "value": {
750
+ "kind": "string"
751
+ }
752
+ },
753
+ {
754
+ "name": "shortName",
755
+ "optional": false,
756
+ "type": "string",
757
+ "value": {
758
+ "kind": "string"
759
+ }
760
+ },
761
+ {
762
+ "name": "categoryId",
763
+ "optional": true,
764
+ "type": "number",
765
+ "value": {
766
+ "kind": "number"
767
+ }
768
+ },
769
+ {
770
+ "name": "start",
771
+ "optional": true,
772
+ "type": "Date",
773
+ "value": {
774
+ "kind": "date"
775
+ }
776
+ },
777
+ {
778
+ "name": "end",
779
+ "optional": true,
780
+ "type": "Date",
781
+ "value": {
782
+ "kind": "date"
783
+ }
784
+ },
785
+ {
786
+ "name": "withUsers",
787
+ "optional": true,
788
+ "type": "boolean",
789
+ "value": {
790
+ "kind": "boolean"
791
+ }
792
+ },
793
+ {
794
+ "name": "visible",
795
+ "optional": true,
796
+ "type": "boolean",
797
+ "value": {
798
+ "kind": "boolean"
799
+ }
800
+ },
801
+ {
802
+ "name": "timeoutMs",
803
+ "optional": true,
804
+ "type": "number",
805
+ "value": {
806
+ "kind": "number"
807
+ }
808
+ }
809
+ ]
810
+ }
811
+ },
812
+ {
813
+ "name": "courseAbilities",
428
814
  "description": "What the person can do in a course, asked of read-only services that need the capability: the activity types they can add (none without `moodle/course:manageactivities`) and the grader report's users (`nopermissions` without `gradereport/grader:view`). Nothing is changed.",
429
815
  "params": [
430
816
  {
@@ -459,6 +845,82 @@ export const COMMANDS = [
459
845
  }
460
846
  ]
461
847
  },
848
+ {
849
+ "name": "courseLogs",
850
+ "description": "A course's logs, newest first, as its logs report lists them: by a user, an activity, a kind of action, and a time span, up to `limit` entries (100 unless given). Moodle filters by user, activity and action; the span is read page by page, stopping at the first entry older than `from`. Every entry's time comes as an ISO date, read back with the site language's own format.",
851
+ "params": [
852
+ {
853
+ "name": "courseId",
854
+ "optional": false,
855
+ "type": "number",
856
+ "value": {
857
+ "kind": "number"
858
+ }
859
+ }
860
+ ],
861
+ "options": {
862
+ "name": "options",
863
+ "optional": true,
864
+ "open": false,
865
+ "fields": [
866
+ {
867
+ "name": "userId",
868
+ "optional": true,
869
+ "type": "number",
870
+ "value": {
871
+ "kind": "number"
872
+ }
873
+ },
874
+ {
875
+ "name": "activityId",
876
+ "optional": true,
877
+ "type": "number",
878
+ "value": {
879
+ "kind": "number"
880
+ }
881
+ },
882
+ {
883
+ "name": "from",
884
+ "optional": true,
885
+ "type": "Date",
886
+ "value": {
887
+ "kind": "date"
888
+ }
889
+ },
890
+ {
891
+ "name": "until",
892
+ "optional": true,
893
+ "type": "Date",
894
+ "value": {
895
+ "kind": "date"
896
+ }
897
+ },
898
+ {
899
+ "name": "action",
900
+ "optional": true,
901
+ "type": "\"create\" | \"view\" | \"update\" | \"delete\" | \"change\"",
902
+ "value": {
903
+ "kind": "enum",
904
+ "values": [
905
+ "create",
906
+ "view",
907
+ "update",
908
+ "delete",
909
+ "change"
910
+ ]
911
+ }
912
+ },
913
+ {
914
+ "name": "limit",
915
+ "optional": true,
916
+ "type": "number",
917
+ "value": {
918
+ "kind": "number"
919
+ }
920
+ }
921
+ ]
922
+ }
923
+ },
462
924
  {
463
925
  "name": "courseRoles",
464
926
  "description": "A user's roles in a course, from their profile there: role links carry the role id in any language.",
@@ -483,7 +945,7 @@ export const COMMANDS = [
483
945
  },
484
946
  {
485
947
  "name": "courseStructure",
486
- "description": "A course's sections and activities; with `details`, each activity's dates and restriction from the course page (slower).",
948
+ "description": "A course's sections and activities; with `details`, each activity's dates and restriction and each section's description, from the course page (slower).",
487
949
  "params": [
488
950
  {
489
951
  "name": "courseId",
@@ -534,12 +996,12 @@ export const COMMANDS = [
534
996
  },
535
997
  {
536
998
  "name": "createActivity",
537
- "description": "Creates an activity or resource of any type at the end of a section, through Moodle's own form, hidden from students unless `visibility` says otherwise. `files` are local paths uploaded to a file resource or folder; a SCORM (`type: \"scorm\"`) takes the first as its package.",
999
+ "description": "Creates an activity or resource of any type at the end of a section, through Moodle's own form, hidden from students unless `visibility` says otherwise. `files` are local paths uploaded to a file resource or folder (a `DraftUpload` puts one in a folder's subfolder); a SCORM (`type: \"scorm\"`) or an H5P activity (`type: \"h5pactivity\"`) takes the first as its package.",
538
1000
  "params": [
539
1001
  {
540
1002
  "name": "input",
541
1003
  "optional": false,
542
- "type": "ActivityFields & { courseId: number; sectionId: number; type: string; files?: string[]; }",
1004
+ "type": "ActivityFields & { courseId: number; sectionId: number; type: string; files?: (string | DraftUpload)[]; }",
543
1005
  "value": {
544
1006
  "kind": "json"
545
1007
  }
@@ -598,6 +1060,50 @@ export const COMMANDS = [
598
1060
  ]
599
1061
  }
600
1062
  },
1063
+ {
1064
+ "name": "createGroup",
1065
+ "description": "Creates a group in a course with its group form (`group/group.php`). Throws `FormError` with Moodle's reason when it refuses (a name already used, an enrolment key another group has).",
1066
+ "params": [
1067
+ {
1068
+ "name": "courseId",
1069
+ "optional": false,
1070
+ "type": "number",
1071
+ "value": {
1072
+ "kind": "number"
1073
+ }
1074
+ },
1075
+ {
1076
+ "name": "settings",
1077
+ "optional": false,
1078
+ "type": "GroupSettings & { name: string; }",
1079
+ "value": {
1080
+ "kind": "json"
1081
+ }
1082
+ }
1083
+ ]
1084
+ },
1085
+ {
1086
+ "name": "createGrouping",
1087
+ "description": "Creates a grouping in a course with its form (`group/grouping.php`); add its groups with `setGroupingGroups`.",
1088
+ "params": [
1089
+ {
1090
+ "name": "courseId",
1091
+ "optional": false,
1092
+ "type": "number",
1093
+ "value": {
1094
+ "kind": "number"
1095
+ }
1096
+ },
1097
+ {
1098
+ "name": "settings",
1099
+ "optional": false,
1100
+ "type": "GroupingSettings & { name: string; }",
1101
+ "value": {
1102
+ "kind": "json"
1103
+ }
1104
+ }
1105
+ ]
1106
+ },
601
1107
  {
602
1108
  "name": "createQuestion",
603
1109
  "description": "Creates one question in a bank through its type's edit form; returns its id. Imports are the way for several; this is for one-offs.",
@@ -655,7 +1161,7 @@ export const COMMANDS = [
655
1161
  "value": {
656
1162
  "kind": "json"
657
1163
  },
658
- "description": "Multichoice, short answer and numerical answers: a fraction of the mark (1 right, 0 wrong, negatives for penalties), the nearest one Moodle offers."
1164
+ "description": "Multichoice, short answer and numerical answers: a fraction of the mark (1 right, 0 wrong, negatives for penalties), the nearest one Moodle offers. A numerical answer's `tolerance` is the error accepted around it."
659
1165
  },
660
1166
  {
661
1167
  "name": "correct",
@@ -672,7 +1178,8 @@ export const COMMANDS = [
672
1178
  "type": "number",
673
1179
  "value": {
674
1180
  "kind": "number"
675
- }
1181
+ },
1182
+ "description": "The bank's category it goes in; a new question goes in the bank's default one when left out."
676
1183
  },
677
1184
  {
678
1185
  "name": "defaultMark",
@@ -767,8 +1274,8 @@ export const COMMANDS = [
767
1274
  ]
768
1275
  },
769
1276
  {
770
- "name": "deleteSection",
771
- "description": "Deletes a section and every activity in it, with their participants' data.",
1277
+ "name": "deleteGradeCategory",
1278
+ "description": "Deletes a grade category. Moodle moves what it held (items and categories) into its parent and deletes the grades of its total; the course's own category can't be deleted.",
772
1279
  "params": [
773
1280
  {
774
1281
  "name": "courseId",
@@ -779,7 +1286,7 @@ export const COMMANDS = [
779
1286
  }
780
1287
  },
781
1288
  {
782
- "name": "sectionId",
1289
+ "name": "categoryId",
783
1290
  "optional": false,
784
1291
  "type": "number",
785
1292
  "value": {
@@ -789,11 +1296,119 @@ export const COMMANDS = [
789
1296
  ]
790
1297
  },
791
1298
  {
792
- "name": "discussion",
793
- "description": "A discussion's posts, oldest first, with their messages as text.",
1299
+ "name": "deleteGradeItem",
1300
+ "description": "Deletes a manual grade item and its grades. An activity's item goes with its activity (Moodle would make it again), so it's refused.",
794
1301
  "params": [
795
1302
  {
796
- "name": "discussionId",
1303
+ "name": "courseId",
1304
+ "optional": false,
1305
+ "type": "number",
1306
+ "value": {
1307
+ "kind": "number"
1308
+ }
1309
+ },
1310
+ {
1311
+ "name": "itemId",
1312
+ "optional": false,
1313
+ "type": "number",
1314
+ "value": {
1315
+ "kind": "number"
1316
+ }
1317
+ }
1318
+ ]
1319
+ },
1320
+ {
1321
+ "name": "deleteGroup",
1322
+ "description": "Deletes a group, as the groups page's \"Delete selected group\" does once confirmed; its members stay in the course.",
1323
+ "params": [
1324
+ {
1325
+ "name": "groupId",
1326
+ "optional": false,
1327
+ "type": "number",
1328
+ "value": {
1329
+ "kind": "number"
1330
+ }
1331
+ }
1332
+ ]
1333
+ },
1334
+ {
1335
+ "name": "deleteGrouping",
1336
+ "description": "Deletes a grouping, as its delete icon does once confirmed; its groups stay.",
1337
+ "params": [
1338
+ {
1339
+ "name": "groupingId",
1340
+ "optional": false,
1341
+ "type": "number",
1342
+ "value": {
1343
+ "kind": "number"
1344
+ }
1345
+ }
1346
+ ]
1347
+ },
1348
+ {
1349
+ "name": "deletePost",
1350
+ "description": "Deletes a post and its replies through Moodle's own confirmation (`post.php?delete=`); a discussion's first post takes the whole discussion. Only a moderator deletes a post with replies, or someone else's. `replies` says how many replies went with it. Throws `ForumError` with Moodle's reason when it refuses.",
1351
+ "params": [
1352
+ {
1353
+ "name": "postId",
1354
+ "optional": false,
1355
+ "type": "number",
1356
+ "value": {
1357
+ "kind": "number"
1358
+ }
1359
+ }
1360
+ ]
1361
+ },
1362
+ {
1363
+ "name": "deleteQuestions",
1364
+ "description": "Deletes questions from a bank, every version of each, as the bank's delete action does: asked, then confirmed. Moodle doesn't delete a question a quiz uses: it hides it, and `hidden` lists those.",
1365
+ "params": [
1366
+ {
1367
+ "name": "activityId",
1368
+ "optional": false,
1369
+ "type": "number",
1370
+ "value": {
1371
+ "kind": "number"
1372
+ }
1373
+ },
1374
+ {
1375
+ "name": "questionIds",
1376
+ "optional": false,
1377
+ "type": "number[]",
1378
+ "value": {
1379
+ "kind": "numbers"
1380
+ }
1381
+ }
1382
+ ]
1383
+ },
1384
+ {
1385
+ "name": "deleteSection",
1386
+ "description": "Deletes a section and every activity in it, with their participants' data.",
1387
+ "params": [
1388
+ {
1389
+ "name": "courseId",
1390
+ "optional": false,
1391
+ "type": "number",
1392
+ "value": {
1393
+ "kind": "number"
1394
+ }
1395
+ },
1396
+ {
1397
+ "name": "sectionId",
1398
+ "optional": false,
1399
+ "type": "number",
1400
+ "value": {
1401
+ "kind": "number"
1402
+ }
1403
+ }
1404
+ ]
1405
+ },
1406
+ {
1407
+ "name": "discussion",
1408
+ "description": "A discussion's posts, oldest first, with their messages as text.",
1409
+ "params": [
1410
+ {
1411
+ "name": "discussionId",
797
1412
  "optional": false,
798
1413
  "type": "number",
799
1414
  "value": {
@@ -913,19 +1528,11 @@ export const COMMANDS = [
913
1528
  }
914
1529
  },
915
1530
  {
916
- "name": "editSection",
917
- "description": "Renames, shows or hides, or moves a section after another one.",
1531
+ "name": "editPost",
1532
+ "description": "Changes a post through Moodle's own post form (`post.php?edit=`), as its author (within the site's editing time) or a moderator: only what's given changes. Returns the post afterwards. Throws `ForumError` with Moodle's reason when it refuses.",
918
1533
  "params": [
919
1534
  {
920
- "name": "courseId",
921
- "optional": false,
922
- "type": "number",
923
- "value": {
924
- "kind": "number"
925
- }
926
- },
927
- {
928
- "name": "sectionId",
1535
+ "name": "postId",
929
1536
  "optional": false,
930
1537
  "type": "number",
931
1538
  "value": {
@@ -934,12 +1541,12 @@ export const COMMANDS = [
934
1541
  }
935
1542
  ],
936
1543
  "options": {
937
- "name": "options",
1544
+ "name": "changes",
938
1545
  "optional": false,
939
1546
  "open": false,
940
1547
  "fields": [
941
1548
  {
942
- "name": "name",
1549
+ "name": "subject",
943
1550
  "optional": true,
944
1551
  "type": "string",
945
1552
  "value": {
@@ -947,41 +1554,29 @@ export const COMMANDS = [
947
1554
  }
948
1555
  },
949
1556
  {
950
- "name": "visible",
1557
+ "name": "message",
951
1558
  "optional": true,
952
- "type": "boolean",
1559
+ "type": "string",
953
1560
  "value": {
954
- "kind": "boolean"
955
- }
1561
+ "kind": "string"
1562
+ },
1563
+ "description": "The new message (HTML), replacing the old one."
956
1564
  },
957
1565
  {
958
- "name": "afterSectionId",
1566
+ "name": "files",
959
1567
  "optional": true,
960
- "type": "number",
1568
+ "type": "{ add?: string[]; remove?: string[]; }",
961
1569
  "value": {
962
- "kind": "number"
963
- }
1570
+ "kind": "json"
1571
+ },
1572
+ "description": "Attachments to add (absolute local paths) and to remove (by name, as the post lists them)."
964
1573
  }
965
1574
  ]
966
1575
  }
967
1576
  },
968
1577
  {
969
- "name": "finishQuizAttempt",
970
- "description": "Submits an attempt for grading, and gives its review when the quiz shows it.",
971
- "params": [
972
- {
973
- "name": "attemptId",
974
- "optional": false,
975
- "type": "number",
976
- "value": {
977
- "kind": "number"
978
- }
979
- }
980
- ]
981
- },
982
- {
983
- "name": "forumDiscussions",
984
- "description": "A forum's discussions, as its page lists them: who started each, replies, last post.",
1578
+ "name": "editQuizSlot",
1579
+ "description": "Changes one slot of a quiz (by its place, from 1): its maximum mark, through the slots' service, and where it is, as dragging it on the edit page does: after another slot (`moveAfter`, 0 for first) and on a page. Moodle lets the mark change after attempts (it regrades them), not the rest.",
985
1580
  "params": [
986
1581
  {
987
1582
  "name": "activityId",
@@ -990,55 +1585,54 @@ export const COMMANDS = [
990
1585
  "value": {
991
1586
  "kind": "number"
992
1587
  }
993
- }
994
- ]
995
- },
996
- {
997
- "name": "getChoice",
998
- "description": "A choice: its options, whether it can be answered or changed, and the person's answer.",
999
- "params": [
1588
+ },
1000
1589
  {
1001
- "name": "activityId",
1590
+ "name": "slot",
1002
1591
  "optional": false,
1003
1592
  "type": "number",
1004
1593
  "value": {
1005
1594
  "kind": "number"
1006
1595
  }
1007
1596
  }
1008
- ]
1009
- },
1010
- {
1011
- "name": "getSurvey",
1012
- "description": "A survey (questionnaire or feedback): whether it can be answered, its intro and messages, and its questions page by page. Its module is found when not given.",
1013
- "params": [
1014
- {
1015
- "name": "activityId",
1016
- "optional": false,
1017
- "type": "number",
1018
- "value": {
1019
- "kind": "number"
1020
- }
1021
- },
1022
- {
1023
- "name": "type",
1024
- "optional": true,
1025
- "type": "SurveyType",
1026
- "value": {
1027
- "kind": "enum",
1028
- "values": [
1029
- "questionnaire",
1030
- "feedback"
1031
- ]
1597
+ ],
1598
+ "options": {
1599
+ "name": "options",
1600
+ "optional": false,
1601
+ "open": false,
1602
+ "fields": [
1603
+ {
1604
+ "name": "maxMark",
1605
+ "optional": true,
1606
+ "type": "number",
1607
+ "value": {
1608
+ "kind": "number"
1609
+ }
1610
+ },
1611
+ {
1612
+ "name": "moveAfter",
1613
+ "optional": true,
1614
+ "type": "number",
1615
+ "value": {
1616
+ "kind": "number"
1617
+ }
1618
+ },
1619
+ {
1620
+ "name": "page",
1621
+ "optional": true,
1622
+ "type": "number",
1623
+ "value": {
1624
+ "kind": "number"
1625
+ }
1032
1626
  }
1033
- }
1034
- ]
1627
+ ]
1628
+ }
1035
1629
  },
1036
1630
  {
1037
- "name": "gradeSubmission",
1038
- "description": "Grades a participant as the grader does: a grade (simple grading), a rubric's level per criterion or a marking guide's score per criterion (by their ids, from `rubric()`), remarks per criterion, feedback comments (HTML), whether to notify, and any other grading field by name. Returns the grade saved and the gradebook's grade, the total Moodle computes for a rubric or a guide.",
1631
+ "name": "editSection",
1632
+ "description": "Renames, shows or hides, describes (`summary`, HTML), restricts (`restrictions`; `{ conditions: [] }` removes them) or moves a section after another one.",
1039
1633
  "params": [
1040
1634
  {
1041
- "name": "activityId",
1635
+ "name": "courseId",
1042
1636
  "optional": false,
1043
1637
  "type": "number",
1044
1638
  "value": {
@@ -1046,7 +1640,7 @@ export const COMMANDS = [
1046
1640
  }
1047
1641
  },
1048
1642
  {
1049
- "name": "userId",
1643
+ "name": "sectionId",
1050
1644
  "optional": false,
1051
1645
  "type": "number",
1052
1646
  "value": {
@@ -1060,42 +1654,23 @@ export const COMMANDS = [
1060
1654
  "open": false,
1061
1655
  "fields": [
1062
1656
  {
1063
- "name": "grade",
1657
+ "name": "name",
1064
1658
  "optional": true,
1065
- "type": "string | number",
1659
+ "type": "string",
1066
1660
  "value": {
1067
1661
  "kind": "string"
1068
1662
  }
1069
1663
  },
1070
1664
  {
1071
- "name": "rubric",
1072
- "optional": true,
1073
- "type": "Record<number, number>",
1074
- "value": {
1075
- "kind": "json"
1076
- },
1077
- "description": "Criterion id → level id."
1078
- },
1079
- {
1080
- "name": "guide",
1081
- "optional": true,
1082
- "type": "Record<number, number>",
1083
- "value": {
1084
- "kind": "json"
1085
- },
1086
- "description": "Criterion id → score."
1087
- },
1088
- {
1089
- "name": "remarks",
1665
+ "name": "visible",
1090
1666
  "optional": true,
1091
- "type": "Record<number, string>",
1667
+ "type": "boolean",
1092
1668
  "value": {
1093
- "kind": "json"
1094
- },
1095
- "description": "Criterion id → remark, for a rubric or a guide."
1669
+ "kind": "boolean"
1670
+ }
1096
1671
  },
1097
1672
  {
1098
- "name": "feedback",
1673
+ "name": "summary",
1099
1674
  "optional": true,
1100
1675
  "type": "string",
1101
1676
  "value": {
@@ -1103,27 +1678,27 @@ export const COMMANDS = [
1103
1678
  }
1104
1679
  },
1105
1680
  {
1106
- "name": "notify",
1681
+ "name": "restrictions",
1107
1682
  "optional": true,
1108
- "type": "boolean",
1683
+ "type": "Restrictions",
1109
1684
  "value": {
1110
- "kind": "boolean"
1685
+ "kind": "json"
1111
1686
  }
1112
1687
  },
1113
1688
  {
1114
- "name": "fields",
1689
+ "name": "afterSectionId",
1115
1690
  "optional": true,
1116
- "type": "Record<string, FieldValue>",
1691
+ "type": "number",
1117
1692
  "value": {
1118
- "kind": "json"
1693
+ "kind": "number"
1119
1694
  }
1120
1695
  }
1121
1696
  ]
1122
1697
  }
1123
1698
  },
1124
1699
  {
1125
- "name": "gradebookSetup",
1126
- "description": "A course's gradebook setup: its categories (aggregation, weights) and grade items (category, maximum, weight).",
1700
+ "name": "enrolUsers",
1701
+ "description": "Enrols users in a course by manual enrolment, as the participants page's \"Enrol users\" dialog does: with `roleId` or the enrolment's default role, from `start` (now, unless given) until `end` (the enrolment's default duration, unless given). Users already enrolled keep their enrolment, with the new dates. Throws `EnrolmentError` with Moodle's reason when it refuses (a role the person can't assign, no manual enrolment).",
1127
1702
  "params": [
1128
1703
  {
1129
1704
  "name": "courseId",
@@ -1132,19 +1707,13 @@ export const COMMANDS = [
1132
1707
  "value": {
1133
1708
  "kind": "number"
1134
1709
  }
1135
- }
1136
- ]
1137
- },
1138
- {
1139
- "name": "graderReport",
1140
- "description": "Everyone's grades in a course as the grader report shows them, page by page, in one group when given. People come as user id and full name only.",
1141
- "params": [
1710
+ },
1142
1711
  {
1143
- "name": "courseId",
1712
+ "name": "userIds",
1144
1713
  "optional": false,
1145
- "type": "number",
1714
+ "type": "number[]",
1146
1715
  "value": {
1147
- "kind": "number"
1716
+ "kind": "numbers"
1148
1717
  }
1149
1718
  }
1150
1719
  ],
@@ -1154,49 +1723,35 @@ export const COMMANDS = [
1154
1723
  "open": false,
1155
1724
  "fields": [
1156
1725
  {
1157
- "name": "group",
1726
+ "name": "roleId",
1158
1727
  "optional": true,
1159
1728
  "type": "number",
1160
1729
  "value": {
1161
1730
  "kind": "number"
1162
1731
  }
1732
+ },
1733
+ {
1734
+ "name": "start",
1735
+ "optional": true,
1736
+ "type": "Date",
1737
+ "value": {
1738
+ "kind": "date"
1739
+ }
1740
+ },
1741
+ {
1742
+ "name": "end",
1743
+ "optional": true,
1744
+ "type": "Date",
1745
+ "value": {
1746
+ "kind": "date"
1747
+ }
1163
1748
  }
1164
1749
  ]
1165
1750
  }
1166
1751
  },
1167
1752
  {
1168
- "name": "grantExtension",
1169
- "description": "Grants participants an extension until a date, through the assignment's extension form (several at once as its bulk action does). Moodle refuses a date before the assignment's due date.",
1170
- "params": [
1171
- {
1172
- "name": "activityId",
1173
- "optional": false,
1174
- "type": "number",
1175
- "value": {
1176
- "kind": "number"
1177
- }
1178
- },
1179
- {
1180
- "name": "userIds",
1181
- "optional": false,
1182
- "type": "number[]",
1183
- "value": {
1184
- "kind": "numbers"
1185
- }
1186
- },
1187
- {
1188
- "name": "until",
1189
- "optional": false,
1190
- "type": "Date",
1191
- "value": {
1192
- "kind": "date"
1193
- }
1194
- }
1195
- ]
1196
- },
1197
- {
1198
- "name": "groups",
1199
- "description": "A course's groups the person can see, with their members' user ids.",
1753
+ "name": "enrolmentMethods",
1754
+ "description": "A course's enrolment methods, in the order Moodle tries them: each one's type, name, whether it's enabled and how many users it enrolled, and from its form the role it gives and, for self enrolment and guest access, whether it asks for a key (never the key), self enrolment's dates and limit. Throws `EnrolmentError` when the person can't manage the course's enrolment methods.",
1200
1755
  "params": [
1201
1756
  {
1202
1757
  "name": "courseId",
@@ -1209,25 +1764,11 @@ export const COMMANDS = [
1209
1764
  ]
1210
1765
  },
1211
1766
  {
1212
- "name": "h5pActivity",
1213
- "description": "An H5P activity: its content type, whether attempts are tracked, and the person's attempts with their scores.",
1214
- "params": [
1215
- {
1216
- "name": "activityId",
1217
- "optional": false,
1218
- "type": "number",
1219
- "value": {
1220
- "kind": "number"
1221
- }
1222
- }
1223
- ]
1224
- },
1225
- {
1226
- "name": "importQuestions",
1227
- "description": "Imports questions into a bank from a GIFT or Moodle XML file (a local path) or text, through the bank's import form; returns the questions created. A file Moodle can't parse comes back as a `QuestionBankError` with its messages, and nothing is imported.",
1767
+ "name": "exportGrades",
1768
+ "description": "Saves a course's grades into `destDir` as Moodle exports them for a teacher: a spreadsheet (`xlsx`, `ods`), comma-separated text (`csv`) or XML, with the items, group, display and feedback chosen as in the export form. Returns the file as `downloadFile` does (never overwriting one). Throws `GradebookError` when the site has that format's export plugin disabled (naming the ones it has), when an item isn't in the course, or when Moodle refuses the export.",
1228
1769
  "params": [
1229
1770
  {
1230
- "name": "activityId",
1771
+ "name": "courseId",
1231
1772
  "optional": false,
1232
1773
  "type": "number",
1233
1774
  "value": {
@@ -1243,48 +1784,71 @@ export const COMMANDS = [
1243
1784
  {
1244
1785
  "name": "format",
1245
1786
  "optional": false,
1246
- "type": "\"gift\" | \"xml\"",
1787
+ "type": "\"ods\" | \"xml\" | \"xlsx\" | \"csv\"",
1247
1788
  "value": {
1248
1789
  "kind": "enum",
1249
1790
  "values": [
1250
- "gift",
1251
- "xml"
1791
+ "ods",
1792
+ "xml",
1793
+ "xlsx",
1794
+ "csv"
1252
1795
  ]
1253
1796
  }
1254
1797
  },
1255
1798
  {
1256
- "name": "file",
1799
+ "name": "itemIds",
1257
1800
  "optional": true,
1258
- "type": "string",
1801
+ "type": "number[]",
1259
1802
  "value": {
1260
- "kind": "string"
1261
- }
1803
+ "kind": "numbers"
1804
+ },
1805
+ "description": "The grade items to export (ids from `graderReport` or `gradebookSetup`); all of them when left out."
1262
1806
  },
1263
1807
  {
1264
- "name": "text",
1808
+ "name": "groupId",
1265
1809
  "optional": true,
1266
- "type": "string",
1810
+ "type": "number",
1267
1811
  "value": {
1268
- "kind": "string"
1269
- }
1812
+ "kind": "number"
1813
+ },
1814
+ "description": "Only this group's members (a group id from `groups`)."
1270
1815
  },
1271
1816
  {
1272
- "name": "categoryId",
1817
+ "name": "display",
1273
1818
  "optional": true,
1274
- "type": "number",
1819
+ "type": "GradeExportDisplay[]",
1275
1820
  "value": {
1276
- "kind": "number"
1277
- }
1821
+ "kind": "json"
1822
+ },
1823
+ "description": "How grades are written; the site's default when left out. XML takes only one."
1824
+ },
1825
+ {
1826
+ "name": "feedback",
1827
+ "optional": true,
1828
+ "type": "boolean",
1829
+ "value": {
1830
+ "kind": "boolean"
1831
+ },
1832
+ "description": "Include each grade's feedback."
1833
+ },
1834
+ {
1835
+ "name": "destDir",
1836
+ "optional": true,
1837
+ "type": "string",
1838
+ "value": {
1839
+ "kind": "string"
1840
+ },
1841
+ "description": "The folder to save the file in (an absolute path); the `Moodle` object's `downloadDir` when left out there."
1278
1842
  }
1279
1843
  ]
1280
1844
  }
1281
1845
  },
1282
1846
  {
1283
- "name": "lessonPage",
1284
- "description": "The lesson page the person is on (starting the lesson the first time).",
1847
+ "name": "finishQuizAttempt",
1848
+ "description": "Submits an attempt for grading, and gives its review when the quiz shows it.",
1285
1849
  "params": [
1286
1850
  {
1287
- "name": "activityId",
1851
+ "name": "attemptId",
1288
1852
  "optional": false,
1289
1853
  "type": "number",
1290
1854
  "value": {
@@ -1294,11 +1858,11 @@ export const COMMANDS = [
1294
1858
  ]
1295
1859
  },
1296
1860
  {
1297
- "name": "listAssignments",
1298
- "description": "The course's assignments, in the course's order, with the section each is in.",
1861
+ "name": "forumDiscussions",
1862
+ "description": "A forum's discussions, as its page lists them: who started each, replies, last post.",
1299
1863
  "params": [
1300
1864
  {
1301
- "name": "courseId",
1865
+ "name": "activityId",
1302
1866
  "optional": false,
1303
1867
  "type": "number",
1304
1868
  "value": {
@@ -1308,36 +1872,25 @@ export const COMMANDS = [
1308
1872
  ]
1309
1873
  },
1310
1874
  {
1311
- "name": "listCourses",
1312
- "description": "The courses the person is enrolled in, as teacher or student.",
1875
+ "name": "forumGrades",
1876
+ "description": "Everyone's whole-forum grade in a forum graded as a whole, as its grader shows them: one per person it can grade (only the active ones when the forum says so), with how it's graded. One service call per person. Throws `NotAForumError` for another activity, and `GradingError` when the forum isn't graded as a whole or uses an advanced grading method.",
1313
1877
  "params": [
1314
1878
  {
1315
- "name": "classification",
1316
- "optional": true,
1317
- "type": "\"all\" | \"inprogress\" | \"future\" | \"past\"",
1879
+ "name": "activityId",
1880
+ "optional": false,
1881
+ "type": "number",
1318
1882
  "value": {
1319
- "kind": "enum",
1320
- "values": [
1321
- "all",
1322
- "inprogress",
1323
- "future",
1324
- "past"
1325
- ]
1883
+ "kind": "number"
1326
1884
  }
1327
1885
  }
1328
- ]
1329
- },
1330
- {
1331
- "name": "logIn",
1332
- "description": "Makes sure there's a session: at once if there is one, else a window where the person logs in (`loginTimeoutMs` by default).",
1333
- "params": [],
1886
+ ],
1334
1887
  "options": {
1335
1888
  "name": "options",
1336
1889
  "optional": true,
1337
1890
  "open": false,
1338
1891
  "fields": [
1339
1892
  {
1340
- "name": "timeoutMs",
1893
+ "name": "groupId",
1341
1894
  "optional": true,
1342
1895
  "type": "number",
1343
1896
  "value": {
@@ -1348,21 +1901,11 @@ export const COMMANDS = [
1348
1901
  }
1349
1902
  },
1350
1903
  {
1351
- "name": "logOut",
1352
- "description": "Logs the person out of Moodle through the user menu's logout link (it carries the sesskey; without one Moodle asks to confirm, and the confirmation is accepted). Returns false when nobody was logged in. Only Moodle's session ends: a single sign-on provider may keep its own.",
1353
- "params": []
1354
- },
1355
- {
1356
- "name": "markNotificationsRead",
1357
- "description": "Marks all the person's notifications read, as the popover's \"Mark all as read\" does; doing it twice changes nothing.",
1358
- "params": []
1359
- },
1360
- {
1361
- "name": "myGrades",
1362
- "description": "The person's own grade report for a course.",
1904
+ "name": "getChoice",
1905
+ "description": "A choice: its options, whether it can be answered or changed, and the person's answer.",
1363
1906
  "params": [
1364
1907
  {
1365
- "name": "courseId",
1908
+ "name": "activityId",
1366
1909
  "optional": false,
1367
1910
  "type": "number",
1368
1911
  "value": {
@@ -1372,28 +1915,8 @@ export const COMMANDS = [
1372
1915
  ]
1373
1916
  },
1374
1917
  {
1375
- "name": "notifications",
1376
- "description": "The person's notifications, newest first, only the unread ones when asked.",
1377
- "params": [],
1378
- "options": {
1379
- "name": "options",
1380
- "optional": true,
1381
- "open": false,
1382
- "fields": [
1383
- {
1384
- "name": "unreadOnly",
1385
- "optional": true,
1386
- "type": "boolean",
1387
- "value": {
1388
- "kind": "boolean"
1389
- }
1390
- }
1391
- ]
1392
- }
1393
- },
1394
- {
1395
- "name": "overrideCompletion",
1396
- "description": "Sets someone's completion of an activity as a teacher does from the progress report; returns the state saved.",
1918
+ "name": "getSurvey",
1919
+ "description": "A survey (questionnaire or feedback): whether it can be answered, its intro and messages, and its questions page by page. Its module is found when not given.",
1397
1920
  "params": [
1398
1921
  {
1399
1922
  "name": "activityId",
@@ -1404,49 +1927,33 @@ export const COMMANDS = [
1404
1927
  }
1405
1928
  },
1406
1929
  {
1407
- "name": "userId",
1408
- "optional": false,
1409
- "type": "number",
1410
- "value": {
1411
- "kind": "number"
1412
- }
1413
- },
1414
- {
1415
- "name": "state",
1416
- "optional": false,
1417
- "type": "\"incomplete\" | \"complete\" | \"complete-pass\" | \"complete-fail\"",
1930
+ "name": "type",
1931
+ "optional": true,
1932
+ "type": "SurveyType",
1418
1933
  "value": {
1419
1934
  "kind": "enum",
1420
1935
  "values": [
1421
- "incomplete",
1422
- "complete",
1423
- "complete-pass",
1424
- "complete-fail"
1936
+ "questionnaire",
1937
+ "feedback"
1425
1938
  ]
1426
1939
  }
1427
1940
  }
1428
1941
  ]
1429
1942
  },
1430
1943
  {
1431
- "name": "participantFilters",
1432
- "description": "The roles and groups the participants page filters by in a course (its filters' options), as the person may use them: every group, or only their own in a course with separate groups. \"No roles\" and \"no group\" left out.",
1944
+ "name": "gradeForumUser",
1945
+ "description": "Gives a person their whole-forum grade, as the forum's grader does: points (out of the forum's maximum), or a scale item by name or value; `null` takes the grade away. Moodle's forum grader has no feedback text. `notify` sends the person Moodle's notification, as the grader's checkbox does. Returns a sentence of what changed and the grade afterwards. Throws `GradingError` when the forum isn't graded as a whole, the grade is out of range or not on the scale, or Moodle refuses it.",
1433
1946
  "params": [
1434
1947
  {
1435
- "name": "courseId",
1948
+ "name": "activityId",
1436
1949
  "optional": false,
1437
1950
  "type": "number",
1438
1951
  "value": {
1439
1952
  "kind": "number"
1440
1953
  }
1441
- }
1442
- ]
1443
- },
1444
- {
1445
- "name": "participants",
1446
- "description": "A course's participants with their roles and groups, as the participants page lists them: only those with a role (its id), in a group, or (`inactiveSince`) who haven't accessed the course since that date, when asked. Each role and group is a filter of its own, so ids come in any language.",
1447
- "params": [
1954
+ },
1448
1955
  {
1449
- "name": "courseId",
1956
+ "name": "userId",
1450
1957
  "optional": false,
1451
1958
  "type": "number",
1452
1959
  "value": {
@@ -1456,72 +1963,76 @@ export const COMMANDS = [
1456
1963
  ],
1457
1964
  "options": {
1458
1965
  "name": "options",
1459
- "optional": true,
1966
+ "optional": false,
1460
1967
  "open": false,
1461
1968
  "fields": [
1462
1969
  {
1463
- "name": "role",
1464
- "optional": true,
1465
- "type": "number",
1466
- "value": {
1467
- "kind": "number"
1468
- }
1469
- },
1470
- {
1471
- "name": "group",
1472
- "optional": true,
1473
- "type": "number",
1970
+ "name": "grade",
1971
+ "optional": false,
1972
+ "type": "string | number",
1474
1973
  "value": {
1475
- "kind": "number"
1974
+ "kind": "string"
1476
1975
  }
1477
1976
  },
1478
1977
  {
1479
- "name": "inactiveSince",
1978
+ "name": "notify",
1480
1979
  "optional": true,
1481
- "type": "Date",
1980
+ "type": "boolean",
1482
1981
  "value": {
1483
- "kind": "date"
1982
+ "kind": "boolean"
1484
1983
  }
1485
1984
  }
1486
1985
  ]
1487
1986
  }
1488
1987
  },
1489
1988
  {
1490
- "name": "pendingActivities",
1491
- "description": "What the person still has to do in a course: activities whose completion is tracked and not complete or, where completion isn't tracked, graded activities without a grade yet.",
1989
+ "name": "gradeQuizQuestion",
1990
+ "description": "Grades one question of a finished attempt by hand, with a comment, through Moodle's comment form (the review's \"Make comment or override mark\"): an essay waiting for grading, or any question whose mark the teacher overrides. The mark is in the question's points (0 to its maximum in the quiz). Returns the attempt's grade afterwards when the results report shows it.",
1492
1991
  "params": [
1493
1992
  {
1494
- "name": "courseId",
1993
+ "name": "attemptId",
1495
1994
  "optional": false,
1496
1995
  "type": "number",
1497
1996
  "value": {
1498
1997
  "kind": "number"
1499
1998
  }
1500
- }
1501
- ]
1502
- },
1503
- {
1504
- "name": "publicSiteInfo",
1505
- "description": "What the site tells anyone before logging in, without the browser.",
1506
- "params": []
1507
- },
1508
- {
1509
- "name": "questionBanks",
1510
- "description": "A course's question banks: its shared ones and the activities' own, as the banks page lists them.",
1511
- "params": [
1999
+ },
1512
2000
  {
1513
- "name": "courseId",
2001
+ "name": "slot",
1514
2002
  "optional": false,
1515
2003
  "type": "number",
1516
2004
  "value": {
1517
2005
  "kind": "number"
1518
2006
  }
1519
2007
  }
1520
- ]
2008
+ ],
2009
+ "options": {
2010
+ "name": "options",
2011
+ "optional": false,
2012
+ "open": false,
2013
+ "fields": [
2014
+ {
2015
+ "name": "mark",
2016
+ "optional": false,
2017
+ "type": "number",
2018
+ "value": {
2019
+ "kind": "number"
2020
+ }
2021
+ },
2022
+ {
2023
+ "name": "comment",
2024
+ "optional": true,
2025
+ "type": "string",
2026
+ "value": {
2027
+ "kind": "string"
2028
+ }
2029
+ }
2030
+ ]
2031
+ }
1521
2032
  },
1522
2033
  {
1523
- "name": "questions",
1524
- "description": "A bank's categories and every question in them, category by category.",
2034
+ "name": "gradeSubmission",
2035
+ "description": "Grades a participant as the grader does: a grade (simple grading), a rubric's level per criterion or a marking guide's score per criterion (by their ids, from `rubric()`), remarks per criterion, feedback comments (HTML), feedback files (local paths that replace the ones the participant has; `[]` removes them), whether to notify, and any other grading field by name. Returns the grade saved and the gradebook's grade, the total Moodle computes for a rubric or a guide, and the feedback files after saving when they were given. Throws `GradingError` when Moodle refuses the grade, or when files are given to an assignment without feedback files.",
1525
2036
  "params": [
1526
2037
  {
1527
2038
  "name": "activityId",
@@ -1530,15 +2041,124 @@ export const COMMANDS = [
1530
2041
  "value": {
1531
2042
  "kind": "number"
1532
2043
  }
2044
+ },
2045
+ {
2046
+ "name": "userId",
2047
+ "optional": false,
2048
+ "type": "number",
2049
+ "value": {
2050
+ "kind": "number"
2051
+ }
1533
2052
  }
1534
- ]
2053
+ ],
2054
+ "options": {
2055
+ "name": "options",
2056
+ "optional": false,
2057
+ "open": false,
2058
+ "fields": [
2059
+ {
2060
+ "name": "grade",
2061
+ "optional": true,
2062
+ "type": "string | number",
2063
+ "value": {
2064
+ "kind": "string"
2065
+ }
2066
+ },
2067
+ {
2068
+ "name": "rubric",
2069
+ "optional": true,
2070
+ "type": "Record<number, number>",
2071
+ "value": {
2072
+ "kind": "json"
2073
+ },
2074
+ "description": "Criterion id → level id."
2075
+ },
2076
+ {
2077
+ "name": "guide",
2078
+ "optional": true,
2079
+ "type": "Record<number, number>",
2080
+ "value": {
2081
+ "kind": "json"
2082
+ },
2083
+ "description": "Criterion id → score."
2084
+ },
2085
+ {
2086
+ "name": "remarks",
2087
+ "optional": true,
2088
+ "type": "Record<number, string>",
2089
+ "value": {
2090
+ "kind": "json"
2091
+ },
2092
+ "description": "Criterion id → remark, for a rubric or a guide."
2093
+ },
2094
+ {
2095
+ "name": "feedback",
2096
+ "optional": true,
2097
+ "type": "string",
2098
+ "value": {
2099
+ "kind": "string"
2100
+ }
2101
+ },
2102
+ {
2103
+ "name": "feedbackFiles",
2104
+ "optional": true,
2105
+ "type": "string[]",
2106
+ "value": {
2107
+ "kind": "strings"
2108
+ },
2109
+ "description": "Local paths (absolute): the participant's feedback files afterwards."
2110
+ },
2111
+ {
2112
+ "name": "workflowState",
2113
+ "optional": true,
2114
+ "type": "\"notmarked\" | \"inmarking\" | \"readyforreview\" | \"inreview\" | \"readyforrelease\" | \"released\"",
2115
+ "value": {
2116
+ "kind": "enum",
2117
+ "values": [
2118
+ "notmarked",
2119
+ "inmarking",
2120
+ "readyforreview",
2121
+ "inreview",
2122
+ "readyforrelease",
2123
+ "released"
2124
+ ]
2125
+ },
2126
+ "description": "With the marking workflow: the state to leave the submission in (\"released\" shows the grade)."
2127
+ },
2128
+ {
2129
+ "name": "applyToGroup",
2130
+ "optional": true,
2131
+ "type": "boolean",
2132
+ "value": {
2133
+ "kind": "boolean"
2134
+ },
2135
+ "description": "With group submissions: grade every member of the participant's group alike (Moodle's default), or only them."
2136
+ },
2137
+ {
2138
+ "name": "notify",
2139
+ "optional": true,
2140
+ "type": "boolean",
2141
+ "value": {
2142
+ "kind": "boolean"
2143
+ }
2144
+ },
2145
+ {
2146
+ "name": "fields",
2147
+ "optional": true,
2148
+ "type": "Record<string, FieldValue>",
2149
+ "value": {
2150
+ "kind": "json"
2151
+ }
2152
+ }
2153
+ ]
2154
+ }
1535
2155
  },
1536
2156
  {
1537
- "name": "quizInfo",
1538
- "description": "A quiz's page as the person sees it: its description and dates, the person's attempts with their summary, and whether they can start one.",
2157
+ "name": "gradebookSetup",
2158
+ "description": "A course's gradebook setup: its categories (aggregation, weights) and grade items (category, maximum, weight).",
1539
2159
  "params": [
1540
2160
  {
1541
- "name": "activityId",
2161
+ "name": "courseId",
1542
2162
  "optional": false,
1543
2163
  "type": "number",
1544
2164
  "value": {
@@ -1548,11 +2168,11 @@ export const COMMANDS = [
1548
2168
  ]
1549
2169
  },
1550
2170
  {
1551
- "name": "quizResults",
1552
- "description": "A quiz's attempts as its grades report shows them: per attempt the user, state, dates, grade and the mark per question; with `responses`, also the answer per question from the responses report. Every page of the report.",
2171
+ "name": "graderReport",
2172
+ "description": "Everyone's grades in a course as the grader report shows them, page by page, in one group when given. People come as user id and full name only.",
1553
2173
  "params": [
1554
2174
  {
1555
- "name": "activityId",
2175
+ "name": "courseId",
1556
2176
  "optional": false,
1557
2177
  "type": "number",
1558
2178
  "value": {
@@ -1566,19 +2186,19 @@ export const COMMANDS = [
1566
2186
  "open": false,
1567
2187
  "fields": [
1568
2188
  {
1569
- "name": "responses",
2189
+ "name": "group",
1570
2190
  "optional": true,
1571
- "type": "boolean",
2191
+ "type": "number",
1572
2192
  "value": {
1573
- "kind": "boolean"
2193
+ "kind": "number"
1574
2194
  }
1575
2195
  }
1576
2196
  ]
1577
2197
  }
1578
2198
  },
1579
2199
  {
1580
- "name": "quizStructure",
1581
- "description": "A quiz's questions as its edit page lists them: slots with their page, question, type, name and mark.",
2200
+ "name": "grantExtension",
2201
+ "description": "Grants participants an extension until a date, through the assignment's extension form (several at once as its bulk action does). Moodle refuses a date before the assignment's due date, and a person without its \"grant extension\" capability only on saving (the form opens for anyone, confirmed empirically on the sandbox, 5.2): both throw.",
1582
2202
  "params": [
1583
2203
  {
1584
2204
  "name": "activityId",
@@ -1587,15 +2207,31 @@ export const COMMANDS = [
1587
2207
  "value": {
1588
2208
  "kind": "number"
1589
2209
  }
2210
+ },
2211
+ {
2212
+ "name": "userIds",
2213
+ "optional": false,
2214
+ "type": "number[]",
2215
+ "value": {
2216
+ "kind": "numbers"
2217
+ }
2218
+ },
2219
+ {
2220
+ "name": "until",
2221
+ "optional": false,
2222
+ "type": "Date",
2223
+ "value": {
2224
+ "kind": "date"
2225
+ }
1590
2226
  }
1591
2227
  ]
1592
2228
  },
1593
2229
  {
1594
- "name": "readAttempt",
1595
- "description": "Every question of an attempt, page by page, with the page each is on.",
2230
+ "name": "groupings",
2231
+ "description": "A course's groupings with their groups' ids, from its groupings page and each grouping's groups page. Throws `MoodleError` with Moodle's refusal for a person who can't manage groups.",
1596
2232
  "params": [
1597
2233
  {
1598
- "name": "attemptId",
2234
+ "name": "courseId",
1599
2235
  "optional": false,
1600
2236
  "type": "number",
1601
2237
  "value": {
@@ -1605,11 +2241,11 @@ export const COMMANDS = [
1605
2241
  ]
1606
2242
  },
1607
2243
  {
1608
- "name": "readReview",
1609
- "description": "A finished attempt's review, as far as the quiz's review options let the person see it.",
2244
+ "name": "groups",
2245
+ "description": "A course's groups the person can see, with their members' user ids.",
1610
2246
  "params": [
1611
2247
  {
1612
- "name": "attemptId",
2248
+ "name": "courseId",
1613
2249
  "optional": false,
1614
2250
  "type": "number",
1615
2251
  "value": {
@@ -1619,11 +2255,1288 @@ export const COMMANDS = [
1619
2255
  ]
1620
2256
  },
1621
2257
  {
1622
- "name": "replyToPost",
1623
- "description": "Replies to a post; returns the new post's id and its discussion's.",
2258
+ "name": "h5pActivity",
2259
+ "description": "An H5P activity: its content type, whether attempts are tracked, and the person's attempts with their scores.",
2260
+ "params": [
2261
+ {
2262
+ "name": "activityId",
2263
+ "optional": false,
2264
+ "type": "number",
2265
+ "value": {
2266
+ "kind": "number"
2267
+ }
2268
+ }
2269
+ ]
2270
+ },
2271
+ {
2272
+ "name": "importActivities",
2273
+ "description": "Imports activities from another course into a course, as Moodle's \"Import\" does: every activity of `fromCourseId`, or only `activityIds`, added to `toCourseId`'s content (with their sections), without users' data. Needs `moodle/restore:restoretargetimport` in the course imported into and `moodle/backup:backuptargetimport` in the other. Returns the activities the course has afterwards that it didn't have before, by id.",
2274
+ "params": [
2275
+ {
2276
+ "name": "fromCourseId",
2277
+ "optional": false,
2278
+ "type": "number",
2279
+ "value": {
2280
+ "kind": "number"
2281
+ }
2282
+ },
2283
+ {
2284
+ "name": "toCourseId",
2285
+ "optional": false,
2286
+ "type": "number",
2287
+ "value": {
2288
+ "kind": "number"
2289
+ }
2290
+ }
2291
+ ],
2292
+ "options": {
2293
+ "name": "options",
2294
+ "optional": true,
2295
+ "open": false,
2296
+ "fields": [
2297
+ {
2298
+ "name": "activityIds",
2299
+ "optional": true,
2300
+ "type": "number[]",
2301
+ "value": {
2302
+ "kind": "numbers"
2303
+ }
2304
+ }
2305
+ ]
2306
+ }
2307
+ },
2308
+ {
2309
+ "name": "importQuestions",
2310
+ "description": "Imports questions into a bank from a GIFT or Moodle XML file (a local path) or text, through the bank's import form; returns the questions created. A file Moodle can't parse comes back as a `QuestionBankError` with its messages, and nothing is imported.",
1624
2311
  "params": [
1625
2312
  {
1626
- "name": "postId",
2313
+ "name": "activityId",
2314
+ "optional": false,
2315
+ "type": "number",
2316
+ "value": {
2317
+ "kind": "number"
2318
+ }
2319
+ }
2320
+ ],
2321
+ "options": {
2322
+ "name": "options",
2323
+ "optional": false,
2324
+ "open": false,
2325
+ "fields": [
2326
+ {
2327
+ "name": "format",
2328
+ "optional": false,
2329
+ "type": "\"xml\" | \"gift\"",
2330
+ "value": {
2331
+ "kind": "enum",
2332
+ "values": [
2333
+ "xml",
2334
+ "gift"
2335
+ ]
2336
+ }
2337
+ },
2338
+ {
2339
+ "name": "file",
2340
+ "optional": true,
2341
+ "type": "string",
2342
+ "value": {
2343
+ "kind": "string"
2344
+ }
2345
+ },
2346
+ {
2347
+ "name": "text",
2348
+ "optional": true,
2349
+ "type": "string",
2350
+ "value": {
2351
+ "kind": "string"
2352
+ }
2353
+ },
2354
+ {
2355
+ "name": "categoryId",
2356
+ "optional": true,
2357
+ "type": "number",
2358
+ "value": {
2359
+ "kind": "number"
2360
+ }
2361
+ }
2362
+ ]
2363
+ }
2364
+ },
2365
+ {
2366
+ "name": "lessonPage",
2367
+ "description": "The lesson page the person is on (starting the lesson the first time).",
2368
+ "params": [
2369
+ {
2370
+ "name": "activityId",
2371
+ "optional": false,
2372
+ "type": "number",
2373
+ "value": {
2374
+ "kind": "number"
2375
+ }
2376
+ }
2377
+ ]
2378
+ },
2379
+ {
2380
+ "name": "listAssignments",
2381
+ "description": "The course's assignments, in the course's order, with the section each is in.",
2382
+ "params": [
2383
+ {
2384
+ "name": "courseId",
2385
+ "optional": false,
2386
+ "type": "number",
2387
+ "value": {
2388
+ "kind": "number"
2389
+ }
2390
+ }
2391
+ ]
2392
+ },
2393
+ {
2394
+ "name": "listCourses",
2395
+ "description": "The courses the person is enrolled in, as teacher or student.",
2396
+ "params": [
2397
+ {
2398
+ "name": "classification",
2399
+ "optional": true,
2400
+ "type": "\"all\" | \"inprogress\" | \"future\" | \"past\"",
2401
+ "value": {
2402
+ "kind": "enum",
2403
+ "values": [
2404
+ "all",
2405
+ "inprogress",
2406
+ "future",
2407
+ "past"
2408
+ ]
2409
+ }
2410
+ }
2411
+ ]
2412
+ },
2413
+ {
2414
+ "name": "logIn",
2415
+ "description": "Makes sure there's a session: at once if there is one, else a window where the person logs in (`loginTimeoutMs` by default).",
2416
+ "params": [],
2417
+ "options": {
2418
+ "name": "options",
2419
+ "optional": true,
2420
+ "open": false,
2421
+ "fields": [
2422
+ {
2423
+ "name": "timeoutMs",
2424
+ "optional": true,
2425
+ "type": "number",
2426
+ "value": {
2427
+ "kind": "number"
2428
+ }
2429
+ }
2430
+ ]
2431
+ }
2432
+ },
2433
+ {
2434
+ "name": "logOut",
2435
+ "description": "Logs the person out of Moodle through the user menu's logout link (it carries the sesskey; without one Moodle asks to confirm, and the confirmation is accepted). Returns false when nobody was logged in. Only Moodle's session ends: a single sign-on provider may keep its own.",
2436
+ "params": []
2437
+ },
2438
+ {
2439
+ "name": "markNotificationsRead",
2440
+ "description": "Marks all the person's notifications read, as the popover's \"Mark all as read\" does; doing it twice changes nothing.",
2441
+ "params": []
2442
+ },
2443
+ {
2444
+ "name": "messageParticipants",
2445
+ "description": "Sends one message to several participants of a course, as the participants page's \"Send a message\" does for the users selected: one private message each, in one call. They are `userIds`, or the participants `participants()` chooses with `role`, `group` and `inactiveSince` (all of them when none is given), the person left out. `sentTo` lists exactly who got it, `refused` who Moodle didn't write to and why (they blocked the person, their privacy settings); someone who may message any user (a teacher, `moodle/site:messageanyuser`) gets through a block, as in Moodle's own page (confirmed empirically, Moodle 5.2). Throws `MessageError` for an empty message or nobody to write to, `NoParticipantsError` when the person can't see the course's participants.",
2446
+ "params": [
2447
+ {
2448
+ "name": "courseId",
2449
+ "optional": false,
2450
+ "type": "number",
2451
+ "value": {
2452
+ "kind": "number"
2453
+ }
2454
+ },
2455
+ {
2456
+ "name": "text",
2457
+ "optional": false,
2458
+ "type": "string",
2459
+ "value": {
2460
+ "kind": "string"
2461
+ }
2462
+ }
2463
+ ],
2464
+ "options": {
2465
+ "name": "selection",
2466
+ "optional": true,
2467
+ "open": false,
2468
+ "fields": [
2469
+ {
2470
+ "name": "userIds",
2471
+ "optional": false,
2472
+ "type": "number[]",
2473
+ "value": {
2474
+ "kind": "numbers"
2475
+ }
2476
+ }
2477
+ ]
2478
+ }
2479
+ },
2480
+ {
2481
+ "name": "myGrades",
2482
+ "description": "The person's own grade report for a course.",
2483
+ "params": [
2484
+ {
2485
+ "name": "courseId",
2486
+ "optional": false,
2487
+ "type": "number",
2488
+ "value": {
2489
+ "kind": "number"
2490
+ }
2491
+ }
2492
+ ]
2493
+ },
2494
+ {
2495
+ "name": "notifications",
2496
+ "description": "The person's notifications, newest first, only the unread ones when asked.",
2497
+ "params": [],
2498
+ "options": {
2499
+ "name": "options",
2500
+ "optional": true,
2501
+ "open": false,
2502
+ "fields": [
2503
+ {
2504
+ "name": "unreadOnly",
2505
+ "optional": true,
2506
+ "type": "boolean",
2507
+ "value": {
2508
+ "kind": "boolean"
2509
+ }
2510
+ }
2511
+ ]
2512
+ }
2513
+ },
2514
+ {
2515
+ "name": "overrideCompletion",
2516
+ "description": "Sets someone's completion of an activity as a teacher does from the progress report; returns the state saved.",
2517
+ "params": [
2518
+ {
2519
+ "name": "activityId",
2520
+ "optional": false,
2521
+ "type": "number",
2522
+ "value": {
2523
+ "kind": "number"
2524
+ }
2525
+ },
2526
+ {
2527
+ "name": "userId",
2528
+ "optional": false,
2529
+ "type": "number",
2530
+ "value": {
2531
+ "kind": "number"
2532
+ }
2533
+ },
2534
+ {
2535
+ "name": "state",
2536
+ "optional": false,
2537
+ "type": "\"incomplete\" | \"complete\" | \"complete-pass\" | \"complete-fail\"",
2538
+ "value": {
2539
+ "kind": "enum",
2540
+ "values": [
2541
+ "incomplete",
2542
+ "complete",
2543
+ "complete-pass",
2544
+ "complete-fail"
2545
+ ]
2546
+ }
2547
+ }
2548
+ ]
2549
+ },
2550
+ {
2551
+ "name": "participantFilters",
2552
+ "description": "The roles and groups the participants page filters by in a course (its filters' options), as the person may use them: every group, or only their own in a course with separate groups. \"No roles\" and \"no group\" left out.",
2553
+ "params": [
2554
+ {
2555
+ "name": "courseId",
2556
+ "optional": false,
2557
+ "type": "number",
2558
+ "value": {
2559
+ "kind": "number"
2560
+ }
2561
+ }
2562
+ ]
2563
+ },
2564
+ {
2565
+ "name": "participants",
2566
+ "description": "A course's participants with their roles and groups, as the participants page lists them: only those with a role (its id), in a group, or (`inactiveSince`) who haven't accessed the course since that date, when asked. Each role and group is a filter of its own, so ids come in any language.",
2567
+ "params": [
2568
+ {
2569
+ "name": "courseId",
2570
+ "optional": false,
2571
+ "type": "number",
2572
+ "value": {
2573
+ "kind": "number"
2574
+ }
2575
+ }
2576
+ ],
2577
+ "options": {
2578
+ "name": "options",
2579
+ "optional": true,
2580
+ "open": false,
2581
+ "fields": [
2582
+ {
2583
+ "name": "role",
2584
+ "optional": true,
2585
+ "type": "number",
2586
+ "value": {
2587
+ "kind": "number"
2588
+ }
2589
+ },
2590
+ {
2591
+ "name": "group",
2592
+ "optional": true,
2593
+ "type": "number",
2594
+ "value": {
2595
+ "kind": "number"
2596
+ }
2597
+ },
2598
+ {
2599
+ "name": "inactiveSince",
2600
+ "optional": true,
2601
+ "type": "Date",
2602
+ "value": {
2603
+ "kind": "date"
2604
+ }
2605
+ }
2606
+ ]
2607
+ }
2608
+ },
2609
+ {
2610
+ "name": "participationReport",
2611
+ "description": "Who took part in an activity of a course, as its participation report counts it: everyone with the role (every role the report offers, unless `roleId`), with how many actions they made there (views or posts only, when `action`; since `since`, when given); those who did nothing come with 0.",
2612
+ "params": [
2613
+ {
2614
+ "name": "courseId",
2615
+ "optional": false,
2616
+ "type": "number",
2617
+ "value": {
2618
+ "kind": "number"
2619
+ }
2620
+ },
2621
+ {
2622
+ "name": "activityId",
2623
+ "optional": false,
2624
+ "type": "number",
2625
+ "value": {
2626
+ "kind": "number"
2627
+ }
2628
+ }
2629
+ ],
2630
+ "options": {
2631
+ "name": "options",
2632
+ "optional": true,
2633
+ "open": false,
2634
+ "fields": [
2635
+ {
2636
+ "name": "roleId",
2637
+ "optional": true,
2638
+ "type": "number",
2639
+ "value": {
2640
+ "kind": "number"
2641
+ }
2642
+ },
2643
+ {
2644
+ "name": "since",
2645
+ "optional": true,
2646
+ "type": "Date",
2647
+ "value": {
2648
+ "kind": "date"
2649
+ }
2650
+ },
2651
+ {
2652
+ "name": "action",
2653
+ "optional": true,
2654
+ "type": "\"view\" | \"post\"",
2655
+ "value": {
2656
+ "kind": "enum",
2657
+ "values": [
2658
+ "view",
2659
+ "post"
2660
+ ]
2661
+ }
2662
+ }
2663
+ ]
2664
+ }
2665
+ },
2666
+ {
2667
+ "name": "pendingActivities",
2668
+ "description": "What the person still has to do in a course: activities whose completion is tracked and not complete or, where completion isn't tracked, graded activities without a grade yet.",
2669
+ "params": [
2670
+ {
2671
+ "name": "courseId",
2672
+ "optional": false,
2673
+ "type": "number",
2674
+ "value": {
2675
+ "kind": "number"
2676
+ }
2677
+ }
2678
+ ]
2679
+ },
2680
+ {
2681
+ "name": "potentialUsers",
2682
+ "description": "Users the person may enrol in a course by manual enrolment, matching `search` anywhere in their name or the identity fields the site shows (all of them, a page of up to 100, when empty), as the \"Enrol users\" dialog finds them. Throws `EnrolmentError` when the course has no manual enrolment the person can use.",
2683
+ "params": [
2684
+ {
2685
+ "name": "courseId",
2686
+ "optional": false,
2687
+ "type": "number",
2688
+ "value": {
2689
+ "kind": "number"
2690
+ }
2691
+ },
2692
+ {
2693
+ "name": "search",
2694
+ "optional": true,
2695
+ "type": "string",
2696
+ "value": {
2697
+ "kind": "string"
2698
+ }
2699
+ }
2700
+ ]
2701
+ },
2702
+ {
2703
+ "name": "publicSiteInfo",
2704
+ "description": "What the site tells anyone before logging in, without the browser.",
2705
+ "params": []
2706
+ },
2707
+ {
2708
+ "name": "questionBanks",
2709
+ "description": "A course's question banks: its shared ones and the activities' own, as the banks page lists them.",
2710
+ "params": [
2711
+ {
2712
+ "name": "courseId",
2713
+ "optional": false,
2714
+ "type": "number",
2715
+ "value": {
2716
+ "kind": "number"
2717
+ }
2718
+ }
2719
+ ]
2720
+ },
2721
+ {
2722
+ "name": "questions",
2723
+ "description": "A bank's categories and every question in them, category by category.",
2724
+ "params": [
2725
+ {
2726
+ "name": "activityId",
2727
+ "optional": false,
2728
+ "type": "number",
2729
+ "value": {
2730
+ "kind": "number"
2731
+ }
2732
+ }
2733
+ ]
2734
+ },
2735
+ {
2736
+ "name": "questionsToGrade",
2737
+ "description": "The questions of a quiz that wait for grading by hand (essays…), as its manual grading report lists them, each with the finished attempts whose answer requires grading (from the results report). People as user id and full name.",
2738
+ "params": [
2739
+ {
2740
+ "name": "activityId",
2741
+ "optional": false,
2742
+ "type": "number",
2743
+ "value": {
2744
+ "kind": "number"
2745
+ }
2746
+ }
2747
+ ]
2748
+ },
2749
+ {
2750
+ "name": "quizInfo",
2751
+ "description": "A quiz's page as the person sees it: its description and dates, the person's attempts with their summary, and whether they can start one.",
2752
+ "params": [
2753
+ {
2754
+ "name": "activityId",
2755
+ "optional": false,
2756
+ "type": "number",
2757
+ "value": {
2758
+ "kind": "number"
2759
+ }
2760
+ }
2761
+ ]
2762
+ },
2763
+ {
2764
+ "name": "quizResults",
2765
+ "description": "A quiz's attempts as its grades report shows them: per attempt the user, state, dates, grade and the mark per question; with `responses`, also the answer per question from the responses report. Every page of the report.",
2766
+ "params": [
2767
+ {
2768
+ "name": "activityId",
2769
+ "optional": false,
2770
+ "type": "number",
2771
+ "value": {
2772
+ "kind": "number"
2773
+ }
2774
+ }
2775
+ ],
2776
+ "options": {
2777
+ "name": "options",
2778
+ "optional": true,
2779
+ "open": false,
2780
+ "fields": [
2781
+ {
2782
+ "name": "responses",
2783
+ "optional": true,
2784
+ "type": "boolean",
2785
+ "value": {
2786
+ "kind": "boolean"
2787
+ }
2788
+ }
2789
+ ]
2790
+ }
2791
+ },
2792
+ {
2793
+ "name": "quizStructure",
2794
+ "description": "A quiz's questions as its edit page lists them: slots with their page, question, type, name and mark, and its sections.",
2795
+ "params": [
2796
+ {
2797
+ "name": "activityId",
2798
+ "optional": false,
2799
+ "type": "number",
2800
+ "value": {
2801
+ "kind": "number"
2802
+ }
2803
+ }
2804
+ ]
2805
+ },
2806
+ {
2807
+ "name": "rate",
2808
+ "description": "Rates a forum post, a glossary entry or a database record as the person, as the rating menu under it does: by a scale item's name, or its number (the points of a point scale). `null` takes the person's rating away. Returns a sentence of what changed and the item's aggregate afterwards (as Moodle shows it, by the activity's aggregation) with the number of ratings. Throws `GradingError` when the item has no rating menu for the person (ratings off, their own item, outside the rating period, or no permission) or the rating isn't on its scale.",
2809
+ "params": [
2810
+ {
2811
+ "name": "item",
2812
+ "optional": false,
2813
+ "type": "RateableItem",
2814
+ "value": {
2815
+ "kind": "json"
2816
+ }
2817
+ },
2818
+ {
2819
+ "name": "rating",
2820
+ "optional": false,
2821
+ "type": "string | number",
2822
+ "value": {
2823
+ "kind": "string"
2824
+ }
2825
+ }
2826
+ ]
2827
+ },
2828
+ {
2829
+ "name": "readAttempt",
2830
+ "description": "Every question of an attempt, page by page, with the page each is on.",
2831
+ "params": [
2832
+ {
2833
+ "name": "attemptId",
2834
+ "optional": false,
2835
+ "type": "number",
2836
+ "value": {
2837
+ "kind": "number"
2838
+ }
2839
+ }
2840
+ ]
2841
+ },
2842
+ {
2843
+ "name": "readReview",
2844
+ "description": "A finished attempt's review, as far as the quiz's review options let the person see it.",
2845
+ "params": [
2846
+ {
2847
+ "name": "attemptId",
2848
+ "optional": false,
2849
+ "type": "number",
2850
+ "value": {
2851
+ "kind": "number"
2852
+ }
2853
+ }
2854
+ ]
2855
+ },
2856
+ {
2857
+ "name": "removeQuizSlot",
2858
+ "description": "Removes a slot (by its place, from 1) from a quiz, as the edit page's delete icon does; the question stays in its bank.",
2859
+ "params": [
2860
+ {
2861
+ "name": "activityId",
2862
+ "optional": false,
2863
+ "type": "number",
2864
+ "value": {
2865
+ "kind": "number"
2866
+ }
2867
+ },
2868
+ {
2869
+ "name": "slot",
2870
+ "optional": false,
2871
+ "type": "number",
2872
+ "value": {
2873
+ "kind": "number"
2874
+ }
2875
+ }
2876
+ ]
2877
+ },
2878
+ {
2879
+ "name": "replyToPost",
2880
+ "description": "Replies to a post; returns the new post's id and its discussion's.",
2881
+ "params": [
2882
+ {
2883
+ "name": "postId",
2884
+ "optional": false,
2885
+ "type": "number",
2886
+ "value": {
2887
+ "kind": "number"
2888
+ }
2889
+ },
2890
+ {
2891
+ "name": "input",
2892
+ "optional": false,
2893
+ "type": "PostInput & { subject?: string; }",
2894
+ "value": {
2895
+ "kind": "json"
2896
+ }
2897
+ }
2898
+ ]
2899
+ },
2900
+ {
2901
+ "name": "resetCourse",
2902
+ "description": "Resets a course for a new year, as Moodle's reset form does: deletes only what's named in `delete` (in every module of the course that has it), unenrols the people with `unenrolRoles` (role ids), moves the course's start date to `start` (and its activities' dates with it), and sets any other of the form's fields by name (`fields`). Nothing is deleted unless asked: the form's own defaults are unticked first. It can't be undone. Returns Moodle's report: per component, what it did and its errors. Needs `moodle/course:reset`.",
2903
+ "params": [
2904
+ {
2905
+ "name": "courseId",
2906
+ "optional": false,
2907
+ "type": "number",
2908
+ "value": {
2909
+ "kind": "number"
2910
+ }
2911
+ }
2912
+ ],
2913
+ "options": {
2914
+ "name": "options",
2915
+ "optional": false,
2916
+ "open": false,
2917
+ "fields": [
2918
+ {
2919
+ "name": "delete",
2920
+ "optional": true,
2921
+ "type": "ResetDeletions",
2922
+ "value": {
2923
+ "kind": "json"
2924
+ }
2925
+ },
2926
+ {
2927
+ "name": "unenrolRoles",
2928
+ "optional": true,
2929
+ "type": "number[]",
2930
+ "value": {
2931
+ "kind": "numbers"
2932
+ }
2933
+ },
2934
+ {
2935
+ "name": "start",
2936
+ "optional": true,
2937
+ "type": "Date",
2938
+ "value": {
2939
+ "kind": "date"
2940
+ }
2941
+ },
2942
+ {
2943
+ "name": "fields",
2944
+ "optional": true,
2945
+ "type": "Record<string, FieldValue>",
2946
+ "value": {
2947
+ "kind": "json"
2948
+ }
2949
+ }
2950
+ ]
2951
+ }
2952
+ },
2953
+ {
2954
+ "name": "restoreCourse",
2955
+ "description": "Restores a backup file (`.mbz`) through Moodle's restore wizard: into a new course in a category (`into: \"new\"`, with `categoryId`, which needs `moodle/course:create` there), or into an existing course (`into: <course id>`), its content added to the course's (`mode: \"merge\"`, the default) or replacing it (`\"replace\"`: the course's content is deleted first). A new course takes the backup's names unless `fullName` and `shortName` are given. Users' data is restored when `withUsers` and the backup has it. An asynchronous restore is waited for up to `timeoutMs` (ten minutes). Needs `moodle/restore:restorecourse` where it restores.",
2956
+ "params": [
2957
+ {
2958
+ "name": "file",
2959
+ "optional": false,
2960
+ "type": "string",
2961
+ "value": {
2962
+ "kind": "string"
2963
+ }
2964
+ }
2965
+ ],
2966
+ "options": {
2967
+ "name": "options",
2968
+ "optional": false,
2969
+ "open": false,
2970
+ "fields": [
2971
+ {
2972
+ "name": "into",
2973
+ "optional": false,
2974
+ "type": "number | \"new\"",
2975
+ "value": {
2976
+ "kind": "string"
2977
+ }
2978
+ },
2979
+ {
2980
+ "name": "categoryId",
2981
+ "optional": true,
2982
+ "type": "number",
2983
+ "value": {
2984
+ "kind": "number"
2985
+ }
2986
+ },
2987
+ {
2988
+ "name": "mode",
2989
+ "optional": true,
2990
+ "type": "\"merge\" | \"replace\"",
2991
+ "value": {
2992
+ "kind": "enum",
2993
+ "values": [
2994
+ "merge",
2995
+ "replace"
2996
+ ]
2997
+ }
2998
+ },
2999
+ {
3000
+ "name": "fullName",
3001
+ "optional": true,
3002
+ "type": "string",
3003
+ "value": {
3004
+ "kind": "string"
3005
+ }
3006
+ },
3007
+ {
3008
+ "name": "shortName",
3009
+ "optional": true,
3010
+ "type": "string",
3011
+ "value": {
3012
+ "kind": "string"
3013
+ }
3014
+ },
3015
+ {
3016
+ "name": "withUsers",
3017
+ "optional": true,
3018
+ "type": "boolean",
3019
+ "value": {
3020
+ "kind": "boolean"
3021
+ }
3022
+ },
3023
+ {
3024
+ "name": "timeoutMs",
3025
+ "optional": true,
3026
+ "type": "number",
3027
+ "value": {
3028
+ "kind": "number"
3029
+ }
3030
+ }
3031
+ ]
3032
+ }
3033
+ },
3034
+ {
3035
+ "name": "rubric",
3036
+ "description": "An assignment's grading method and, for a rubric or a marking guide, its criteria with the ids `gradeSubmission` takes: read from the grader's panel for its first participant.",
3037
+ "params": [
3038
+ {
3039
+ "name": "activityId",
3040
+ "optional": false,
3041
+ "type": "number",
3042
+ "value": {
3043
+ "kind": "number"
3044
+ }
3045
+ }
3046
+ ]
3047
+ },
3048
+ {
3049
+ "name": "saveSubmission",
3050
+ "description": "Saves the submission's online text and adds files, as \"Save changes\" on the edit page does; gives the assignment afterwards.",
3051
+ "params": [
3052
+ {
3053
+ "name": "activityId",
3054
+ "optional": false,
3055
+ "type": "number",
3056
+ "value": {
3057
+ "kind": "number"
3058
+ }
3059
+ }
3060
+ ],
3061
+ "options": {
3062
+ "name": "input",
3063
+ "optional": false,
3064
+ "open": false,
3065
+ "fields": [
3066
+ {
3067
+ "name": "onlineText",
3068
+ "optional": true,
3069
+ "type": "string",
3070
+ "value": {
3071
+ "kind": "string"
3072
+ }
3073
+ },
3074
+ {
3075
+ "name": "files",
3076
+ "optional": true,
3077
+ "type": "string[]",
3078
+ "value": {
3079
+ "kind": "strings"
3080
+ }
3081
+ }
3082
+ ]
3083
+ }
3084
+ },
3085
+ {
3086
+ "name": "scorm",
3087
+ "description": "A SCORM activity as the person sees it: its attempts (allowed and made), the grading method, the grade reported and each attempt's, and its SCOs with the person's status and score in the last attempt. Moodle doesn't show a SCORM's version on its page: `openScorm` tells it.",
3088
+ "params": [
3089
+ {
3090
+ "name": "activityId",
3091
+ "optional": false,
3092
+ "type": "number",
3093
+ "value": {
3094
+ "kind": "number"
3095
+ }
3096
+ }
3097
+ ]
3098
+ },
3099
+ {
3100
+ "name": "sendMessage",
3101
+ "description": "Sends a private message to a user, as the messaging drawer does; returns the message and its conversation.",
3102
+ "params": [
3103
+ {
3104
+ "name": "userId",
3105
+ "optional": false,
3106
+ "type": "number",
3107
+ "value": {
3108
+ "kind": "number"
3109
+ }
3110
+ },
3111
+ {
3112
+ "name": "text",
3113
+ "optional": false,
3114
+ "type": "string",
3115
+ "value": {
3116
+ "kind": "string"
3117
+ }
3118
+ }
3119
+ ]
3120
+ },
3121
+ {
3122
+ "name": "setCompletion",
3123
+ "description": "Marks the person's own completion of an activity with manual completion, done or not, as its \"Mark as done\" button does; doing it twice changes nothing. An activity that completes on its own gives a `CompletionError`.",
3124
+ "params": [
3125
+ {
3126
+ "name": "activityId",
3127
+ "optional": false,
3128
+ "type": "number",
3129
+ "value": {
3130
+ "kind": "number"
3131
+ }
3132
+ },
3133
+ {
3134
+ "name": "done",
3135
+ "optional": false,
3136
+ "type": "boolean",
3137
+ "value": {
3138
+ "kind": "boolean"
3139
+ }
3140
+ }
3141
+ ]
3142
+ },
3143
+ {
3144
+ "name": "setDiscussionState",
3145
+ "description": "Pins or unpins, locks or unlocks a discussion, as the discussion list's menu does; what's already so is left alone. Returns the discussion as the forum lists it afterwards.",
3146
+ "params": [
3147
+ {
3148
+ "name": "activityId",
3149
+ "optional": false,
3150
+ "type": "number",
3151
+ "value": {
3152
+ "kind": "number"
3153
+ }
3154
+ },
3155
+ {
3156
+ "name": "discussionId",
3157
+ "optional": false,
3158
+ "type": "number",
3159
+ "value": {
3160
+ "kind": "number"
3161
+ }
3162
+ }
3163
+ ],
3164
+ "options": {
3165
+ "name": "options",
3166
+ "optional": false,
3167
+ "open": false,
3168
+ "fields": [
3169
+ {
3170
+ "name": "pinned",
3171
+ "optional": true,
3172
+ "type": "boolean",
3173
+ "value": {
3174
+ "kind": "boolean"
3175
+ }
3176
+ },
3177
+ {
3178
+ "name": "locked",
3179
+ "optional": true,
3180
+ "type": "boolean",
3181
+ "value": {
3182
+ "kind": "boolean"
3183
+ }
3184
+ }
3185
+ ]
3186
+ }
3187
+ },
3188
+ {
3189
+ "name": "setEnrolmentMethod",
3190
+ "description": "Sets an enrolment method with its form: by id, or the course's first method of a type (`{ type: \"self\" }`), added when the course has none and the \"Add method\" menu offers it. Only what's given changes. Returns the method afterwards. Throws `EnrolmentError` for a method the course doesn't have or can't add, `FormError` with Moodle's reason when it refuses the form (a key required by the site, an end before the start).",
3191
+ "params": [
3192
+ {
3193
+ "name": "courseId",
3194
+ "optional": false,
3195
+ "type": "number",
3196
+ "value": {
3197
+ "kind": "number"
3198
+ }
3199
+ },
3200
+ {
3201
+ "name": "method",
3202
+ "optional": false,
3203
+ "type": "number | { type: string; }",
3204
+ "value": {
3205
+ "kind": "json"
3206
+ }
3207
+ }
3208
+ ],
3209
+ "options": {
3210
+ "name": "settings",
3211
+ "optional": false,
3212
+ "open": false,
3213
+ "fields": [
3214
+ {
3215
+ "name": "enabled",
3216
+ "optional": true,
3217
+ "type": "boolean",
3218
+ "value": {
3219
+ "kind": "boolean"
3220
+ }
3221
+ },
3222
+ {
3223
+ "name": "key",
3224
+ "optional": true,
3225
+ "type": "string",
3226
+ "value": {
3227
+ "kind": "string"
3228
+ },
3229
+ "description": "Self enrolment and guest access: the key to ask for; \"\" removes it."
3230
+ },
3231
+ {
3232
+ "name": "start",
3233
+ "optional": true,
3234
+ "type": "Date",
3235
+ "value": {
3236
+ "kind": "date"
3237
+ },
3238
+ "description": "Self enrolment: from when and until when students may enrol; `null` removes the limit."
3239
+ },
3240
+ {
3241
+ "name": "end",
3242
+ "optional": true,
3243
+ "type": "Date",
3244
+ "value": {
3245
+ "kind": "date"
3246
+ }
3247
+ },
3248
+ {
3249
+ "name": "roleId",
3250
+ "optional": true,
3251
+ "type": "number",
3252
+ "value": {
3253
+ "kind": "number"
3254
+ },
3255
+ "description": "The role it gives (manual and self enrolment)."
3256
+ },
3257
+ {
3258
+ "name": "maxUsers",
3259
+ "optional": true,
3260
+ "type": "number",
3261
+ "value": {
3262
+ "kind": "number"
3263
+ },
3264
+ "description": "Self enrolment: the most users it enrols; 0 for no limit."
3265
+ },
3266
+ {
3267
+ "name": "welcome",
3268
+ "optional": true,
3269
+ "type": "string | false",
3270
+ "value": {
3271
+ "kind": "json"
3272
+ },
3273
+ "description": "Self enrolment: the welcome message to send (from the course contact unless another sender is set); `false` sends none."
3274
+ }
3275
+ ]
3276
+ }
3277
+ },
3278
+ {
3279
+ "name": "setGrade",
3280
+ "description": "Sets a person's grade in a grade item through the gradebook's single view report, as a teacher does there: a manual item takes the grade; an activity's or a category's is overridden (Moodle keeps the override until it's taken off with `override: false`). Feedback and excluding from the totals go the same way. Returns a sentence of what changed and the grade afterwards. Throws `GradebookError` when the item or the person isn't in the course's gradebook, the grade is locked, or Moodle refuses the value (out of range, a scale item it doesn't have).",
3281
+ "params": [
3282
+ {
3283
+ "name": "courseId",
3284
+ "optional": false,
3285
+ "type": "number",
3286
+ "value": {
3287
+ "kind": "number"
3288
+ }
3289
+ },
3290
+ {
3291
+ "name": "itemId",
3292
+ "optional": false,
3293
+ "type": "number",
3294
+ "value": {
3295
+ "kind": "number"
3296
+ }
3297
+ },
3298
+ {
3299
+ "name": "userId",
3300
+ "optional": false,
3301
+ "type": "number",
3302
+ "value": {
3303
+ "kind": "number"
3304
+ }
3305
+ }
3306
+ ],
3307
+ "options": {
3308
+ "name": "options",
3309
+ "optional": false,
3310
+ "open": false,
3311
+ "fields": [
3312
+ {
3313
+ "name": "grade",
3314
+ "optional": true,
3315
+ "type": "string | number",
3316
+ "value": {
3317
+ "kind": "string"
3318
+ },
3319
+ "description": "A number, or a scale item's name or value for a scale; `null` empties the grade."
3320
+ },
3321
+ {
3322
+ "name": "feedback",
3323
+ "optional": true,
3324
+ "type": "string",
3325
+ "value": {
3326
+ "kind": "string"
3327
+ },
3328
+ "description": "Feedback text; an empty string removes it."
3329
+ },
3330
+ {
3331
+ "name": "override",
3332
+ "optional": true,
3333
+ "type": "boolean",
3334
+ "value": {
3335
+ "kind": "boolean"
3336
+ },
3337
+ "description": "Override the activity's or category's grade. Giving a grade or feedback to an activity's or a category's item overrides it unless this says `false`; `false` alone gives the grade back to the activity."
3338
+ },
3339
+ {
3340
+ "name": "excluded",
3341
+ "optional": true,
3342
+ "type": "boolean",
3343
+ "value": {
3344
+ "kind": "boolean"
3345
+ },
3346
+ "description": "Leave the grade out of the totals."
3347
+ }
3348
+ ]
3349
+ }
3350
+ },
3351
+ {
3352
+ "name": "setGroupMembers",
3353
+ "description": "Adds and removes a group's members (user ids), as its members page does. Only the course's participants can be added: ids the page doesn't offer (not enrolled, or already members) and members not in it are left as they were and named in `changed`. Returns the members afterwards.",
3354
+ "params": [
3355
+ {
3356
+ "name": "groupId",
3357
+ "optional": false,
3358
+ "type": "number",
3359
+ "value": {
3360
+ "kind": "number"
3361
+ }
3362
+ }
3363
+ ],
3364
+ "options": {
3365
+ "name": "options",
3366
+ "optional": false,
3367
+ "open": false,
3368
+ "fields": [
3369
+ {
3370
+ "name": "add",
3371
+ "optional": true,
3372
+ "type": "number[]",
3373
+ "value": {
3374
+ "kind": "numbers"
3375
+ }
3376
+ },
3377
+ {
3378
+ "name": "remove",
3379
+ "optional": true,
3380
+ "type": "number[]",
3381
+ "value": {
3382
+ "kind": "numbers"
3383
+ }
3384
+ }
3385
+ ]
3386
+ }
3387
+ },
3388
+ {
3389
+ "name": "setGroupingGroups",
3390
+ "description": "Makes a grouping's groups exactly `groupIds`, as its groups page adds and removes them. Groups of other courses aren't offered there and are left out, named in `changed`. Returns the groups afterwards.",
3391
+ "params": [
3392
+ {
3393
+ "name": "groupingId",
3394
+ "optional": false,
3395
+ "type": "number",
3396
+ "value": {
3397
+ "kind": "number"
3398
+ }
3399
+ },
3400
+ {
3401
+ "name": "groupIds",
3402
+ "optional": false,
3403
+ "type": "number[]",
3404
+ "value": {
3405
+ "kind": "numbers"
3406
+ }
3407
+ }
3408
+ ]
3409
+ },
3410
+ {
3411
+ "name": "setQuestionStatus",
3412
+ "description": "Sets a question ready (quizzes can use it) or draft, as the bank's status menu does, through its service.",
3413
+ "params": [
3414
+ {
3415
+ "name": "questionId",
3416
+ "optional": false,
3417
+ "type": "number",
3418
+ "value": {
3419
+ "kind": "number"
3420
+ }
3421
+ },
3422
+ {
3423
+ "name": "status",
3424
+ "optional": false,
3425
+ "type": "\"ready\" | \"draft\"",
3426
+ "value": {
3427
+ "kind": "enum",
3428
+ "values": [
3429
+ "ready",
3430
+ "draft"
3431
+ ]
3432
+ }
3433
+ }
3434
+ ]
3435
+ },
3436
+ {
3437
+ "name": "setQuizOverride",
3438
+ "description": "Sets a user override on a quiz, through its override form: other opening and closing dates, a time limit in minutes, or a number of attempts (0 unlimited); what isn't given stays the quiz's.",
3439
+ "params": [
3440
+ {
3441
+ "name": "activityId",
3442
+ "optional": false,
3443
+ "type": "number",
3444
+ "value": {
3445
+ "kind": "number"
3446
+ }
3447
+ },
3448
+ {
3449
+ "name": "userId",
3450
+ "optional": false,
3451
+ "type": "number",
3452
+ "value": {
3453
+ "kind": "number"
3454
+ }
3455
+ }
3456
+ ],
3457
+ "options": {
3458
+ "name": "options",
3459
+ "optional": false,
3460
+ "open": false,
3461
+ "fields": [
3462
+ {
3463
+ "name": "open",
3464
+ "optional": true,
3465
+ "type": "Date",
3466
+ "value": {
3467
+ "kind": "date"
3468
+ }
3469
+ },
3470
+ {
3471
+ "name": "close",
3472
+ "optional": true,
3473
+ "type": "Date",
3474
+ "value": {
3475
+ "kind": "date"
3476
+ }
3477
+ },
3478
+ {
3479
+ "name": "timeLimitMinutes",
3480
+ "optional": true,
3481
+ "type": "number",
3482
+ "value": {
3483
+ "kind": "number"
3484
+ }
3485
+ },
3486
+ {
3487
+ "name": "attempts",
3488
+ "optional": true,
3489
+ "type": "number",
3490
+ "value": {
3491
+ "kind": "number"
3492
+ }
3493
+ }
3494
+ ]
3495
+ }
3496
+ },
3497
+ {
3498
+ "name": "setQuizPages",
3499
+ "description": "Sets a quiz's pages: `perPage` questions a page (0 for all on one), as the edit page's \"Repaginate\" does, or page breaks exactly after the given slots (and nowhere else), as its page break icons do one by one.",
3500
+ "params": [
3501
+ {
3502
+ "name": "activityId",
3503
+ "optional": false,
3504
+ "type": "number",
3505
+ "value": {
3506
+ "kind": "number"
3507
+ }
3508
+ }
3509
+ ],
3510
+ "options": {
3511
+ "name": "pages",
3512
+ "optional": false,
3513
+ "open": false,
3514
+ "fields": [
3515
+ {
3516
+ "name": "perPage",
3517
+ "optional": false,
3518
+ "type": "number",
3519
+ "value": {
3520
+ "kind": "number"
3521
+ }
3522
+ }
3523
+ ]
3524
+ }
3525
+ },
3526
+ {
3527
+ "name": "setUserRoles",
3528
+ "description": "Sets a user's roles in a course, as the participants page's roles column does: gives the roles in `roleIds` the person may assign, and takes away the others the person may assign. Roles the person can't assign that the user already holds, and those from elsewhere (a category, an enrolment that protects them), stay. Returns the user's roles afterwards, as that column shows them. Throws `EnrolmentError` with Moodle's reason for a role the person can't assign or a user not enrolled.",
3529
+ "params": [
3530
+ {
3531
+ "name": "courseId",
3532
+ "optional": false,
3533
+ "type": "number",
3534
+ "value": {
3535
+ "kind": "number"
3536
+ }
3537
+ },
3538
+ {
3539
+ "name": "userId",
1627
3540
  "optional": false,
1628
3541
  "type": "number",
1629
3542
  "value": {
@@ -1631,18 +3544,18 @@ export const COMMANDS = [
1631
3544
  }
1632
3545
  },
1633
3546
  {
1634
- "name": "input",
3547
+ "name": "roleIds",
1635
3548
  "optional": false,
1636
- "type": "PostInput & { subject?: string; }",
3549
+ "type": "number[]",
1637
3550
  "value": {
1638
- "kind": "json"
3551
+ "kind": "numbers"
1639
3552
  }
1640
3553
  }
1641
3554
  ]
1642
3555
  },
1643
3556
  {
1644
- "name": "rubric",
1645
- "description": "An assignment's grading method and, for a rubric or a marking guide, its criteria with the ids `gradeSubmission` takes: read from the grader's panel for its first participant.",
3557
+ "name": "setWorkflowState",
3558
+ "description": "Sets the marking workflow state of participants' submissions, as the grading table's \"Set marking workflow state\" does; \"released\" shows them their grades, notifying them when `notify` is true (the form's default is not to). With several markers, it sets the submission's overall state.",
1646
3559
  "params": [
1647
3560
  {
1648
3561
  "name": "activityId",
@@ -1651,49 +3564,50 @@ export const COMMANDS = [
1651
3564
  "value": {
1652
3565
  "kind": "number"
1653
3566
  }
1654
- }
1655
- ]
1656
- },
1657
- {
1658
- "name": "saveSubmission",
1659
- "description": "Saves the submission's online text and adds files, as \"Save changes\" on the edit page does; gives the assignment afterwards.",
1660
- "params": [
3567
+ },
1661
3568
  {
1662
- "name": "activityId",
3569
+ "name": "userIds",
1663
3570
  "optional": false,
1664
- "type": "number",
3571
+ "type": "number[]",
1665
3572
  "value": {
1666
- "kind": "number"
3573
+ "kind": "numbers"
3574
+ }
3575
+ },
3576
+ {
3577
+ "name": "state",
3578
+ "optional": false,
3579
+ "type": "\"inmarking\" | \"readyforreview\" | \"inreview\" | \"readyforrelease\" | \"released\"",
3580
+ "value": {
3581
+ "kind": "enum",
3582
+ "values": [
3583
+ "inmarking",
3584
+ "readyforreview",
3585
+ "inreview",
3586
+ "readyforrelease",
3587
+ "released"
3588
+ ]
1667
3589
  }
1668
3590
  }
1669
3591
  ],
1670
3592
  "options": {
1671
- "name": "input",
1672
- "optional": false,
3593
+ "name": "options",
3594
+ "optional": true,
1673
3595
  "open": false,
1674
3596
  "fields": [
1675
3597
  {
1676
- "name": "onlineText",
1677
- "optional": true,
1678
- "type": "string",
1679
- "value": {
1680
- "kind": "string"
1681
- }
1682
- },
1683
- {
1684
- "name": "files",
3598
+ "name": "notify",
1685
3599
  "optional": true,
1686
- "type": "string[]",
3600
+ "type": "boolean",
1687
3601
  "value": {
1688
- "kind": "strings"
3602
+ "kind": "boolean"
1689
3603
  }
1690
3604
  }
1691
3605
  ]
1692
3606
  }
1693
3607
  },
1694
3608
  {
1695
- "name": "scorm",
1696
- "description": "A SCORM activity as the person sees it: its attempts (allowed and made), the grading method, the grade reported and each attempt's, and its SCOs with the person's status and score in the last attempt. Moodle doesn't show a SCORM's version on its page: `openScorm` tells it.",
3609
+ "name": "setWorkshopPhase",
3610
+ "description": "Switches a workshop to a phase, as its page's phase links do, confirming Moodle's question (any phase, forwards or back; Moodle allocates nothing and calculates no grades on its own when it switches). Returns a sentence of what changed and the phase afterwards. Throws `WorkshopError` when the person can't switch the workshop's phases (Moodle's `mod/workshop:switchphase`, a teacher's) or the id isn't a workshop's.",
1697
3611
  "params": [
1698
3612
  {
1699
3613
  "name": "activityId",
@@ -1702,15 +3616,35 @@ export const COMMANDS = [
1702
3616
  "value": {
1703
3617
  "kind": "number"
1704
3618
  }
3619
+ },
3620
+ {
3621
+ "name": "phase",
3622
+ "optional": false,
3623
+ "type": "WorkshopPhase",
3624
+ "value": {
3625
+ "kind": "enum",
3626
+ "values": [
3627
+ "setup",
3628
+ "submission",
3629
+ "assessment",
3630
+ "evaluation",
3631
+ "closed"
3632
+ ]
3633
+ }
1705
3634
  }
1706
3635
  ]
1707
3636
  },
1708
3637
  {
1709
- "name": "sendMessage",
1710
- "description": "Sends a private message to a user, as the messaging drawer does; returns the message and its conversation.",
3638
+ "name": "siteName",
3639
+ "description": "The site's name, from its public settings; `undefined` where the mobile app support is off.",
3640
+ "params": []
3641
+ },
3642
+ {
3643
+ "name": "startDiscussion",
3644
+ "description": "Starts a discussion in a forum; returns its id.",
1711
3645
  "params": [
1712
3646
  {
1713
- "name": "userId",
3647
+ "name": "activityId",
1714
3648
  "optional": false,
1715
3649
  "type": "number",
1716
3650
  "value": {
@@ -1718,18 +3652,18 @@ export const COMMANDS = [
1718
3652
  }
1719
3653
  },
1720
3654
  {
1721
- "name": "text",
3655
+ "name": "input",
1722
3656
  "optional": false,
1723
- "type": "string",
3657
+ "type": "PostInput & { subject: string; }",
1724
3658
  "value": {
1725
- "kind": "string"
3659
+ "kind": "json"
1726
3660
  }
1727
3661
  }
1728
3662
  ]
1729
3663
  },
1730
3664
  {
1731
- "name": "setCompletion",
1732
- "description": "Marks the person's own completion of an activity with manual completion, done or not, as its \"Mark as done\" button does; doing it twice changes nothing. An activity that completes on its own gives a `CompletionError`.",
3665
+ "name": "startQuizAttempt",
3666
+ "description": "Starts an attempt, or continues the one in progress, and gives its questions.",
1733
3667
  "params": [
1734
3668
  {
1735
3669
  "name": "activityId",
@@ -1738,20 +3672,12 @@ export const COMMANDS = [
1738
3672
  "value": {
1739
3673
  "kind": "number"
1740
3674
  }
1741
- },
1742
- {
1743
- "name": "done",
1744
- "optional": false,
1745
- "type": "boolean",
1746
- "value": {
1747
- "kind": "boolean"
1748
- }
1749
3675
  }
1750
3676
  ]
1751
3677
  },
1752
3678
  {
1753
- "name": "setDiscussionState",
1754
- "description": "Pins or unpins, locks or unlocks a discussion, as the discussion list's menu does; what's already so is left alone. Returns the discussion as the forum lists it afterwards.",
3679
+ "name": "studentAssignment",
3680
+ "description": "An assignment as the student sees it: its description and files, dates, the submission's status and files, the feedback, and whether it can be edited or submitted now.",
1755
3681
  "params": [
1756
3682
  {
1757
3683
  "name": "activityId",
@@ -1760,9 +3686,15 @@ export const COMMANDS = [
1760
3686
  "value": {
1761
3687
  "kind": "number"
1762
3688
  }
1763
- },
3689
+ }
3690
+ ]
3691
+ },
3692
+ {
3693
+ "name": "submitForGrading",
3694
+ "description": "Submits the saved submission for grading, accepting the site's statement when it asks for one (`acceptStatement`, once the person agrees; a bare boolean as before 0.2 too); gives the assignment afterwards.",
3695
+ "params": [
1764
3696
  {
1765
- "name": "discussionId",
3697
+ "name": "activityId",
1766
3698
  "optional": false,
1767
3699
  "type": "number",
1768
3700
  "value": {
@@ -1772,19 +3704,11 @@ export const COMMANDS = [
1772
3704
  ],
1773
3705
  "options": {
1774
3706
  "name": "options",
1775
- "optional": false,
3707
+ "optional": true,
1776
3708
  "open": false,
1777
3709
  "fields": [
1778
3710
  {
1779
- "name": "pinned",
1780
- "optional": true,
1781
- "type": "boolean",
1782
- "value": {
1783
- "kind": "boolean"
1784
- }
1785
- },
1786
- {
1787
- "name": "locked",
3711
+ "name": "acceptStatement",
1788
3712
  "optional": true,
1789
3713
  "type": "boolean",
1790
3714
  "value": {
@@ -1795,8 +3719,8 @@ export const COMMANDS = [
1795
3719
  }
1796
3720
  },
1797
3721
  {
1798
- "name": "setQuizOverride",
1799
- "description": "Sets a user override on a quiz, through its override form: other opening and closing dates, a time limit in minutes, or a number of attempts (0 unlimited); what isn't given stays the quiz's.",
3722
+ "name": "submitSurvey",
3723
+ "description": "Fills the survey page by page with `responses` (field name → value) and submits it on the last page. Every name is checked against the form first, so nothing is sent with a wrong one.",
1800
3724
  "params": [
1801
3725
  {
1802
3726
  "name": "activityId",
@@ -1807,65 +3731,40 @@ export const COMMANDS = [
1807
3731
  }
1808
3732
  },
1809
3733
  {
1810
- "name": "userId",
3734
+ "name": "responses",
1811
3735
  "optional": false,
1812
- "type": "number",
3736
+ "type": "Record<string, string>",
1813
3737
  "value": {
1814
- "kind": "number"
3738
+ "kind": "json"
1815
3739
  }
1816
3740
  }
1817
3741
  ],
1818
3742
  "options": {
1819
3743
  "name": "options",
1820
- "optional": false,
3744
+ "optional": true,
1821
3745
  "open": false,
1822
3746
  "fields": [
1823
3747
  {
1824
- "name": "open",
1825
- "optional": true,
1826
- "type": "Date",
1827
- "value": {
1828
- "kind": "date"
1829
- }
1830
- },
1831
- {
1832
- "name": "close",
1833
- "optional": true,
1834
- "type": "Date",
1835
- "value": {
1836
- "kind": "date"
1837
- }
1838
- },
1839
- {
1840
- "name": "timeLimitMinutes",
1841
- "optional": true,
1842
- "type": "number",
1843
- "value": {
1844
- "kind": "number"
1845
- }
1846
- },
1847
- {
1848
- "name": "attempts",
3748
+ "name": "type",
1849
3749
  "optional": true,
1850
- "type": "number",
3750
+ "type": "SurveyType",
1851
3751
  "value": {
1852
- "kind": "number"
3752
+ "kind": "enum",
3753
+ "values": [
3754
+ "questionnaire",
3755
+ "feedback"
3756
+ ]
1853
3757
  }
1854
3758
  }
1855
3759
  ]
1856
3760
  }
1857
3761
  },
1858
3762
  {
1859
- "name": "siteName",
1860
- "description": "The site's name, from its public settings; `undefined` where the mobile app support is off.",
1861
- "params": []
1862
- },
1863
- {
1864
- "name": "startDiscussion",
1865
- "description": "Starts a discussion in a forum; returns its id.",
3763
+ "name": "unenrolUser",
3764
+ "description": "Unenrols a user from a course: removes every enrolment of theirs the person may remove (its unenrol link on the participants page), with their roles and group memberships in the course, as that link does. `changed` and `removed` say which ones (by enrolment method's name), `kept` those the person may not remove (a cohort sync, another teacher's method). Throws `EnrolmentError` when the user isn't enrolled.",
1866
3765
  "params": [
1867
3766
  {
1868
- "name": "activityId",
3767
+ "name": "courseId",
1869
3768
  "optional": false,
1870
3769
  "type": "number",
1871
3770
  "value": {
@@ -1873,18 +3772,38 @@ export const COMMANDS = [
1873
3772
  }
1874
3773
  },
1875
3774
  {
1876
- "name": "input",
3775
+ "name": "userId",
1877
3776
  "optional": false,
1878
- "type": "PostInput & { subject: string; }",
3777
+ "type": "number",
1879
3778
  "value": {
1880
- "kind": "json"
3779
+ "kind": "number"
1881
3780
  }
1882
3781
  }
1883
3782
  ]
1884
3783
  },
1885
3784
  {
1886
- "name": "startQuizAttempt",
1887
- "description": "Starts an attempt, or continues the one in progress, and gives its questions.",
3785
+ "name": "upcomingEvents",
3786
+ "description": "The person's upcoming events, as the calendar's \"Upcoming events\" view lists them, in one course or all.",
3787
+ "params": [],
3788
+ "options": {
3789
+ "name": "options",
3790
+ "optional": true,
3791
+ "open": false,
3792
+ "fields": [
3793
+ {
3794
+ "name": "courseId",
3795
+ "optional": true,
3796
+ "type": "number",
3797
+ "value": {
3798
+ "kind": "number"
3799
+ }
3800
+ }
3801
+ ]
3802
+ }
3803
+ },
3804
+ {
3805
+ "name": "updateActivity",
3806
+ "description": "Changes an existing activity through its form: only what's given changes. A file resource's or folder's files stay as they are unless `files` says what to add, remove or replace.",
1888
3807
  "params": [
1889
3808
  {
1890
3809
  "name": "activityId",
@@ -1893,29 +3812,76 @@ export const COMMANDS = [
1893
3812
  "value": {
1894
3813
  "kind": "number"
1895
3814
  }
3815
+ },
3816
+ {
3817
+ "name": "input",
3818
+ "optional": false,
3819
+ "type": "ActivityFields & { files?: FileChanges; }",
3820
+ "value": {
3821
+ "kind": "json"
3822
+ }
1896
3823
  }
1897
3824
  ]
1898
3825
  },
1899
3826
  {
1900
- "name": "studentAssignment",
1901
- "description": "An assignment as the student sees it: its description and files, dates, the submission's status and files, the feedback, and whether it can be edited or submitted now.",
3827
+ "name": "updateCourse",
3828
+ "description": "Changes a course's full name, short name, summary (HTML) or any other setting by its form field name, through the course's settings form; returns the course as `listCourses` gives it. Moodle's refusals (a short name already taken) come back as `FormError` by field.",
1902
3829
  "params": [
1903
3830
  {
1904
- "name": "activityId",
3831
+ "name": "courseId",
1905
3832
  "optional": false,
1906
3833
  "type": "number",
1907
3834
  "value": {
1908
3835
  "kind": "number"
1909
3836
  }
1910
3837
  }
1911
- ]
3838
+ ],
3839
+ "options": {
3840
+ "name": "options",
3841
+ "optional": false,
3842
+ "open": false,
3843
+ "fields": [
3844
+ {
3845
+ "name": "fullName",
3846
+ "optional": true,
3847
+ "type": "string",
3848
+ "value": {
3849
+ "kind": "string"
3850
+ }
3851
+ },
3852
+ {
3853
+ "name": "shortName",
3854
+ "optional": true,
3855
+ "type": "string",
3856
+ "value": {
3857
+ "kind": "string"
3858
+ }
3859
+ },
3860
+ {
3861
+ "name": "summary",
3862
+ "optional": true,
3863
+ "type": "string",
3864
+ "value": {
3865
+ "kind": "string"
3866
+ }
3867
+ },
3868
+ {
3869
+ "name": "settings",
3870
+ "optional": true,
3871
+ "type": "Record<string, FieldValue>",
3872
+ "value": {
3873
+ "kind": "json"
3874
+ }
3875
+ }
3876
+ ]
3877
+ }
1912
3878
  },
1913
3879
  {
1914
- "name": "submitForGrading",
1915
- "description": "Submits the saved submission for grading, accepting the site's statement when it asks for one (`acceptStatement`, once the person agrees; a bare boolean as before 0.2 too); gives the assignment afterwards.",
3880
+ "name": "updateEvent",
3881
+ "description": "Changes a calendar event through the calendar's own form, opened on it: only what's given changes. A new start keeps the event's length unless a new one is given. Returns the event as the calendar has it afterwards.",
1916
3882
  "params": [
1917
3883
  {
1918
- "name": "activityId",
3884
+ "name": "eventId",
1919
3885
  "optional": false,
1920
3886
  "type": "number",
1921
3887
  "value": {
@@ -1924,27 +3890,79 @@ export const COMMANDS = [
1924
3890
  }
1925
3891
  ],
1926
3892
  "options": {
1927
- "name": "options",
1928
- "optional": true,
3893
+ "name": "changes",
3894
+ "optional": false,
1929
3895
  "open": false,
1930
3896
  "fields": [
1931
3897
  {
1932
- "name": "acceptStatement",
3898
+ "name": "name",
3899
+ "optional": true,
3900
+ "type": "string",
3901
+ "value": {
3902
+ "kind": "string"
3903
+ }
3904
+ },
3905
+ {
3906
+ "name": "description",
3907
+ "optional": true,
3908
+ "type": "string",
3909
+ "value": {
3910
+ "kind": "string"
3911
+ },
3912
+ "description": "HTML, sent as written."
3913
+ },
3914
+ {
3915
+ "name": "start",
3916
+ "optional": true,
3917
+ "type": "Date",
3918
+ "value": {
3919
+ "kind": "date"
3920
+ }
3921
+ },
3922
+ {
3923
+ "name": "durationMinutes",
3924
+ "optional": true,
3925
+ "type": "number",
3926
+ "value": {
3927
+ "kind": "number"
3928
+ },
3929
+ "description": "The new length in minutes; 0 leaves the event without one."
3930
+ },
3931
+ {
3932
+ "name": "until",
3933
+ "optional": true,
3934
+ "type": "Date",
3935
+ "value": {
3936
+ "kind": "date"
3937
+ },
3938
+ "description": "The new end, instead of a length in minutes."
3939
+ },
3940
+ {
3941
+ "name": "location",
3942
+ "optional": true,
3943
+ "type": "string",
3944
+ "value": {
3945
+ "kind": "string"
3946
+ }
3947
+ },
3948
+ {
3949
+ "name": "wholeSeries",
1933
3950
  "optional": true,
1934
3951
  "type": "boolean",
1935
3952
  "value": {
1936
3953
  "kind": "boolean"
1937
- }
3954
+ },
3955
+ "description": "For an event of a repeated series: change every event of the series (Moodle's default), or only this one."
1938
3956
  }
1939
3957
  ]
1940
3958
  }
1941
3959
  },
1942
3960
  {
1943
- "name": "submitSurvey",
1944
- "description": "Fills the survey page by page with `responses` (field name → value) and submits it on the last page. Every name is checked against the form first, so nothing is sent with a wrong one.",
3961
+ "name": "updateGradeCategory",
3962
+ "description": "Changes a grade category: its name, its aggregation, its weight in its parent (percent, overriding Natural's automatic one), or moves it into another category. Returns the category afterwards.",
1945
3963
  "params": [
1946
3964
  {
1947
- "name": "activityId",
3965
+ "name": "courseId",
1948
3966
  "optional": false,
1949
3967
  "type": "number",
1950
3968
  "value": {
@@ -1952,45 +3970,56 @@ export const COMMANDS = [
1952
3970
  }
1953
3971
  },
1954
3972
  {
1955
- "name": "responses",
3973
+ "name": "categoryId",
1956
3974
  "optional": false,
1957
- "type": "Record<string, string>",
3975
+ "type": "number",
1958
3976
  "value": {
1959
- "kind": "json"
3977
+ "kind": "number"
1960
3978
  }
1961
3979
  }
1962
3980
  ],
1963
3981
  "options": {
1964
3982
  "name": "options",
1965
- "optional": true,
3983
+ "optional": false,
1966
3984
  "open": false,
1967
3985
  "fields": [
1968
3986
  {
1969
- "name": "type",
3987
+ "name": "name",
1970
3988
  "optional": true,
1971
- "type": "SurveyType",
3989
+ "type": "string",
3990
+ "value": {
3991
+ "kind": "string"
3992
+ }
3993
+ },
3994
+ {
3995
+ "name": "aggregation",
3996
+ "optional": true,
3997
+ "type": "\"mean\" | \"median\" | \"lowest\" | \"highest\" | \"mode\" | \"weighted-mean\" | \"simple-weighted-mean\" | \"mean-with-extra-credits\" | \"natural\"",
1972
3998
  "value": {
1973
3999
  "kind": "enum",
1974
4000
  "values": [
1975
- "questionnaire",
1976
- "feedback"
4001
+ "mean",
4002
+ "median",
4003
+ "lowest",
4004
+ "highest",
4005
+ "mode",
4006
+ "weighted-mean",
4007
+ "simple-weighted-mean",
4008
+ "mean-with-extra-credits",
4009
+ "natural"
1977
4010
  ]
1978
4011
  }
1979
- }
1980
- ]
1981
- }
1982
- },
1983
- {
1984
- "name": "upcomingEvents",
1985
- "description": "The person's upcoming events, as the calendar's \"Upcoming events\" view lists them, in one course or all.",
1986
- "params": [],
1987
- "options": {
1988
- "name": "options",
1989
- "optional": true,
1990
- "open": false,
1991
- "fields": [
4012
+ },
1992
4013
  {
1993
- "name": "courseId",
4014
+ "name": "weight",
4015
+ "optional": true,
4016
+ "type": "number",
4017
+ "value": {
4018
+ "kind": "number"
4019
+ }
4020
+ },
4021
+ {
4022
+ "name": "parentId",
1994
4023
  "optional": true,
1995
4024
  "type": "number",
1996
4025
  "value": {
@@ -2001,11 +4030,19 @@ export const COMMANDS = [
2001
4030
  }
2002
4031
  },
2003
4032
  {
2004
- "name": "updateActivity",
2005
- "description": "Changes an existing activity through its form: only what's given changes; files stay as they are.",
4033
+ "name": "updateGradeItem",
4034
+ "description": "Changes a grade item: moves it into a category, sets its weight (percent, overriding Natural's automatic one), or its maximum grade (a manual item's; an activity's is set in the activity). Returns the item afterwards.",
2006
4035
  "params": [
2007
4036
  {
2008
- "name": "activityId",
4037
+ "name": "courseId",
4038
+ "optional": false,
4039
+ "type": "number",
4040
+ "value": {
4041
+ "kind": "number"
4042
+ }
4043
+ },
4044
+ {
4045
+ "name": "itemId",
2009
4046
  "optional": false,
2010
4047
  "type": "number",
2011
4048
  "value": {
@@ -2014,75 +4051,43 @@ export const COMMANDS = [
2014
4051
  }
2015
4052
  ],
2016
4053
  "options": {
2017
- "name": "input",
4054
+ "name": "options",
2018
4055
  "optional": false,
2019
4056
  "open": false,
2020
4057
  "fields": [
2021
4058
  {
2022
- "name": "name",
4059
+ "name": "category",
2023
4060
  "optional": true,
2024
- "type": "string",
4061
+ "type": "number",
2025
4062
  "value": {
2026
- "kind": "string"
4063
+ "kind": "number"
2027
4064
  }
2028
4065
  },
2029
4066
  {
2030
- "name": "description",
2031
- "optional": true,
2032
- "type": "string",
2033
- "value": {
2034
- "kind": "string"
2035
- },
2036
- "description": "The description (HTML), shown on the activity's page."
2037
- },
2038
- {
2039
- "name": "content",
2040
- "optional": true,
2041
- "type": "string",
2042
- "value": {
2043
- "kind": "string"
2044
- },
2045
- "description": "A page's content, or a label's text (HTML)."
2046
- },
2047
- {
2048
- "name": "url",
2049
- "optional": true,
2050
- "type": "string",
2051
- "value": {
2052
- "kind": "string"
2053
- },
2054
- "description": "A URL resource's target."
2055
- },
2056
- {
2057
- "name": "visibility",
4067
+ "name": "weight",
2058
4068
  "optional": true,
2059
- "type": "\"shown\" | \"hidden\" | \"stealth\"",
4069
+ "type": "number",
2060
4070
  "value": {
2061
- "kind": "enum",
2062
- "values": [
2063
- "shown",
2064
- "hidden",
2065
- "stealth"
2066
- ]
4071
+ "kind": "number"
2067
4072
  }
2068
4073
  },
2069
4074
  {
2070
- "name": "settings",
4075
+ "name": "maxGrade",
2071
4076
  "optional": true,
2072
- "type": "Record<string, FieldValue>",
4077
+ "type": "number",
2073
4078
  "value": {
2074
- "kind": "json"
4079
+ "kind": "number"
2075
4080
  }
2076
4081
  }
2077
4082
  ]
2078
4083
  }
2079
4084
  },
2080
4085
  {
2081
- "name": "updateCourse",
2082
- "description": "Changes a course's full name, short name, summary (HTML) or any other setting by its form field name, through the course's settings form; returns the course as `listCourses` gives it. Moodle's refusals (a short name already taken) come back as `FormError` by field.",
4086
+ "name": "updateGroup",
4087
+ "description": "Changes a group's name, description, ID number or enrolment key with its form; what isn't given stays.",
2083
4088
  "params": [
2084
4089
  {
2085
- "name": "courseId",
4090
+ "name": "groupId",
2086
4091
  "optional": false,
2087
4092
  "type": "number",
2088
4093
  "value": {
@@ -2091,12 +4096,12 @@ export const COMMANDS = [
2091
4096
  }
2092
4097
  ],
2093
4098
  "options": {
2094
- "name": "options",
4099
+ "name": "settings",
2095
4100
  "optional": false,
2096
4101
  "open": false,
2097
4102
  "fields": [
2098
4103
  {
2099
- "name": "fullName",
4104
+ "name": "name",
2100
4105
  "optional": true,
2101
4106
  "type": "string",
2102
4107
  "value": {
@@ -2104,15 +4109,16 @@ export const COMMANDS = [
2104
4109
  }
2105
4110
  },
2106
4111
  {
2107
- "name": "shortName",
4112
+ "name": "description",
2108
4113
  "optional": true,
2109
4114
  "type": "string",
2110
4115
  "value": {
2111
4116
  "kind": "string"
2112
- }
4117
+ },
4118
+ "description": "HTML."
2113
4119
  },
2114
4120
  {
2115
- "name": "summary",
4121
+ "name": "idNumber",
2116
4122
  "optional": true,
2117
4123
  "type": "string",
2118
4124
  "value": {
@@ -2120,22 +4126,23 @@ export const COMMANDS = [
2120
4126
  }
2121
4127
  },
2122
4128
  {
2123
- "name": "settings",
4129
+ "name": "enrolmentKey",
2124
4130
  "optional": true,
2125
- "type": "Record<string, FieldValue>",
4131
+ "type": "string",
2126
4132
  "value": {
2127
- "kind": "json"
2128
- }
4133
+ "kind": "string"
4134
+ },
4135
+ "description": "The key that puts a student enrolling with self enrolment in this group."
2129
4136
  }
2130
4137
  ]
2131
4138
  }
2132
4139
  },
2133
4140
  {
2134
- "name": "updateGradeItem",
2135
- "description": "Changes a grade item: moves it into a category, sets its weight (percent, overriding Natural's automatic one), or its maximum grade (a manual item's; an activity's is set in the activity). Returns the item afterwards.",
4141
+ "name": "updateQuestion",
4142
+ "description": "Changes a question of a bank through its type's edit form, with the same inputs as `createQuestion` and only what's given (`answers` replaces them all). Saving makes a new version of the question, with an id of its own: the one returned, which quizzes using the latest version get from then on.",
2136
4143
  "params": [
2137
4144
  {
2138
- "name": "courseId",
4145
+ "name": "activityId",
2139
4146
  "optional": false,
2140
4147
  "type": "number",
2141
4148
  "value": {
@@ -2143,7 +4150,7 @@ export const COMMANDS = [
2143
4150
  }
2144
4151
  },
2145
4152
  {
2146
- "name": "itemId",
4153
+ "name": "questionId",
2147
4154
  "optional": false,
2148
4155
  "type": "number",
2149
4156
  "value": {
@@ -2152,28 +4159,65 @@ export const COMMANDS = [
2152
4159
  }
2153
4160
  ],
2154
4161
  "options": {
2155
- "name": "options",
4162
+ "name": "input",
2156
4163
  "optional": false,
2157
4164
  "open": false,
2158
4165
  "fields": [
2159
4166
  {
2160
- "name": "category",
4167
+ "name": "name",
2161
4168
  "optional": true,
2162
- "type": "number",
4169
+ "type": "string",
2163
4170
  "value": {
2164
- "kind": "number"
4171
+ "kind": "string"
2165
4172
  }
2166
4173
  },
2167
4174
  {
2168
- "name": "weight",
4175
+ "name": "fields",
4176
+ "optional": true,
4177
+ "type": "Record<string, FieldValue>",
4178
+ "value": {
4179
+ "kind": "json"
4180
+ },
4181
+ "description": "Any other field of the type's form, by name."
4182
+ },
4183
+ {
4184
+ "name": "text",
4185
+ "optional": true,
4186
+ "type": "string",
4187
+ "value": {
4188
+ "kind": "string"
4189
+ },
4190
+ "description": "The question's text (HTML)."
4191
+ },
4192
+ {
4193
+ "name": "answers",
4194
+ "optional": true,
4195
+ "type": "{ text: string; fraction: number; feedback?: string; tolerance?: number; }[]",
4196
+ "value": {
4197
+ "kind": "json"
4198
+ },
4199
+ "description": "Multichoice, short answer and numerical answers: a fraction of the mark (1 right, 0 wrong, negatives for penalties), the nearest one Moodle offers. A numerical answer's `tolerance` is the error accepted around it."
4200
+ },
4201
+ {
4202
+ "name": "correct",
4203
+ "optional": true,
4204
+ "type": "boolean",
4205
+ "value": {
4206
+ "kind": "boolean"
4207
+ },
4208
+ "description": "True/false: the right answer."
4209
+ },
4210
+ {
4211
+ "name": "categoryId",
2169
4212
  "optional": true,
2170
4213
  "type": "number",
2171
4214
  "value": {
2172
4215
  "kind": "number"
2173
- }
4216
+ },
4217
+ "description": "The bank's category it goes in; a new question goes in the bank's default one when left out."
2174
4218
  },
2175
4219
  {
2176
- "name": "maxGrade",
4220
+ "name": "defaultMark",
2177
4221
  "optional": true,
2178
4222
  "type": "number",
2179
4223
  "value": {
@@ -2185,7 +4229,7 @@ export const COMMANDS = [
2185
4229
  },
2186
4230
  {
2187
4231
  "name": "userById",
2188
- "description": "A user by id, or `undefined` when Moodle gives nobody (no such user, or not one the person may see).",
4232
+ "description": "A user by id, or `undefined` when there's nobody: no such user, one the person may not see, or a deleted account. Moodle keeps a deleted account's record and its user service still gives it to an administrator, renamed, with the email replaced by an MD5 hash of the old username (`delete_user`, confirmed empirically on the sandbox, 5.2); the driver treats it as gone.",
2189
4233
  "params": [
2190
4234
  {
2191
4235
  "name": "userId",
@@ -2210,6 +4254,20 @@ export const COMMANDS = [
2210
4254
  }
2211
4255
  }
2212
4256
  ]
4257
+ },
4258
+ {
4259
+ "name": "workshopInfo",
4260
+ "description": "A workshop's phase, and its report as the workshop's page shows it to a teacher: every submission (its author, title, and grade once calculated) and every assessment (reviewer, the submission's author, the grade it gives, its weight, the grade for assessing once calculated), all of its pages. The report is Moodle's own: it shows from the submission phase on to those who can see every submission, in the course's current group; for anyone else the lists are empty. Grades are out of the workshop's grade for submission, as Moodle shows them. Throws `WorkshopError` for an activity that isn't a workshop the person can view.",
4261
+ "params": [
4262
+ {
4263
+ "name": "activityId",
4264
+ "optional": false,
4265
+ "type": "number",
4266
+ "value": {
4267
+ "kind": "number"
4268
+ }
4269
+ }
4270
+ ]
2213
4271
  }
2214
4272
  ];
2215
4273
  /** Methods with no command: they give a browser tab, which means nothing once the command exits. */