utn-mcp 0.8.2 → 0.9.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 (87) hide show
  1. package/README.md +29 -2
  2. package/build/aula-virtual/client/client.d.ts +97 -0
  3. package/build/aula-virtual/client/client.js +21 -0
  4. package/build/aula-virtual/client/credentials.d.ts +10 -0
  5. package/build/aula-virtual/client/link.d.ts +21 -0
  6. package/build/aula-virtual/client/local-session.d.ts +23 -0
  7. package/build/aula-virtual/client/moodle-api.d.ts +25 -0
  8. package/build/aula-virtual/client/moodle-api.js +28 -4
  9. package/build/aula-virtual/client/regionals.d.ts +47 -0
  10. package/build/aula-virtual/client/session.d.ts +12 -0
  11. package/build/aula-virtual/client/sso-login.d.ts +60 -0
  12. package/build/aula-virtual/client/stored-session.d.ts +32 -0
  13. package/build/aula-virtual/client/types.d.ts +173 -0
  14. package/build/aula-virtual/format/actions.d.ts +57 -0
  15. package/build/aula-virtual/format/activities.d.ts +86 -0
  16. package/build/aula-virtual/format/address.d.ts +36 -0
  17. package/build/aula-virtual/format/address.js +11 -0
  18. package/build/aula-virtual/format/fields.d.ts +11 -0
  19. package/build/aula-virtual/format/files.d.ts +32 -0
  20. package/build/aula-virtual/format/files.js +2 -2
  21. package/build/aula-virtual/format/navigate.d.ts +213 -0
  22. package/build/aula-virtual/format/study-pack.d.ts +33 -0
  23. package/build/aula-virtual/format/study-pack.js +199 -0
  24. package/build/aula-virtual/format/submission.d.ts +40 -0
  25. package/build/aula-virtual/login.d.ts +6 -0
  26. package/build/aula-virtual/tools.d.ts +4 -0
  27. package/build/aula-virtual/tools.js +40 -0
  28. package/build/autogestion/client/catalog.d.ts +20 -0
  29. package/build/autogestion/client/catalog.js +22 -0
  30. package/build/autogestion/client/connector.d.ts +61 -0
  31. package/build/autogestion/client/connector.js +31 -0
  32. package/build/autogestion/client/credentials.d.ts +5 -0
  33. package/build/autogestion/client/credentials.js +40 -0
  34. package/build/autogestion/client/install.d.ts +14 -0
  35. package/build/autogestion/client/install.js +72 -0
  36. package/build/autogestion/client/installed-systems.d.ts +7 -0
  37. package/build/autogestion/client/installed-systems.js +58 -0
  38. package/build/autogestion/client/local-session.d.ts +17 -0
  39. package/build/autogestion/client/local-session.js +37 -0
  40. package/build/autogestion/client/session.d.ts +14 -0
  41. package/build/autogestion/client/session.js +1 -0
  42. package/build/autogestion/client/types.d.ts +49 -0
  43. package/build/autogestion/client/types.js +1 -0
  44. package/build/autogestion/format/correlatividades.d.ts +4 -0
  45. package/build/autogestion/format/correlatividades.js +4 -0
  46. package/build/autogestion/format/estado-academico.d.ts +4 -0
  47. package/build/autogestion/format/estado-academico.js +4 -0
  48. package/build/autogestion/format/examenes.d.ts +3 -0
  49. package/build/autogestion/format/examenes.js +8 -0
  50. package/build/autogestion/format/notas-parciales.d.ts +3 -0
  51. package/build/autogestion/format/notas-parciales.js +8 -0
  52. package/build/autogestion/login.d.ts +11 -0
  53. package/build/autogestion/login.js +59 -0
  54. package/build/autogestion/tools.d.ts +3 -0
  55. package/build/autogestion/tools.js +73 -0
  56. package/build/http.d.ts +22 -0
  57. package/build/index.d.ts +2 -0
  58. package/build/index.js +11 -1
  59. package/build/oauth/access.d.ts +18 -0
  60. package/build/oauth/admin.d.ts +8 -0
  61. package/build/oauth/admin.js +51 -10
  62. package/build/oauth/expiring.d.ts +25 -0
  63. package/build/oauth/pending-login.d.ts +20 -0
  64. package/build/oauth/redirects.d.ts +20 -0
  65. package/build/oauth/server.d.ts +22 -0
  66. package/build/server.d.ts +9 -0
  67. package/build/server.js +21 -2
  68. package/build/shared/documents/index.d.ts +33 -0
  69. package/build/shared/documents/merge.d.ts +32 -0
  70. package/build/shared/documents/merge.js +197 -0
  71. package/build/shared/documents/office.d.ts +9 -0
  72. package/build/shared/documents/pdf.d.ts +2 -0
  73. package/build/shared/documents/png.d.ts +2 -0
  74. package/build/shared/documents/zip.d.ts +18 -0
  75. package/build/shared/html.d.ts +6 -0
  76. package/build/shared/html.js +7 -1
  77. package/build/shared/http.d.ts +6 -0
  78. package/build/shared/input.d.ts +7 -0
  79. package/build/shared/load-env.d.ts +1 -0
  80. package/build/shared/logger.d.ts +5 -0
  81. package/build/shared/pages.d.ts +6 -0
  82. package/build/shared/paths.d.ts +10 -0
  83. package/build/shared/paths.js +4 -0
  84. package/build/shared/store/session-store.d.ts +77 -0
  85. package/build/shared/store/sqlite-store.d.ts +36 -0
  86. package/build/shared/uploads.d.ts +62 -0
  87. package/package.json +9 -1
@@ -0,0 +1,173 @@
1
+ export interface SiteInfo {
2
+ sitename: string;
3
+ username: string;
4
+ fullname: string;
5
+ userid: number;
6
+ release: string;
7
+ functions: {
8
+ name: string;
9
+ version: string;
10
+ }[];
11
+ }
12
+ export interface Course {
13
+ id: number;
14
+ shortname: string;
15
+ fullname: string;
16
+ visible: number;
17
+ progress?: number | null;
18
+ lastaccess?: number | null;
19
+ }
20
+ export interface CourseModuleContent {
21
+ type: "file" | "url" | "content";
22
+ filename: string;
23
+ filepath: string | null;
24
+ filesize: number;
25
+ fileurl: string;
26
+ timemodified: number | null;
27
+ mimetype?: string;
28
+ }
29
+ export interface CourseModule {
30
+ id: number;
31
+ name: string;
32
+ modname: string;
33
+ /** id del plugin, no del módulo: es lo que piden las funciones mod_* (p. ej. forumid). */
34
+ instance: number;
35
+ url?: string;
36
+ description?: string;
37
+ uservisible: boolean;
38
+ availabilityinfo?: string;
39
+ dates?: {
40
+ label: string;
41
+ timestamp: number;
42
+ }[];
43
+ contents?: CourseModuleContent[];
44
+ }
45
+ export interface CourseSection {
46
+ id: number;
47
+ name: string;
48
+ section: number;
49
+ summary: string;
50
+ uservisible?: boolean;
51
+ modules: CourseModule[];
52
+ }
53
+ export interface ForumDiscussion {
54
+ /** id de la discusión; es el que pide mod_forum_get_discussion_posts. */
55
+ discussion: number;
56
+ subject: string;
57
+ message: string;
58
+ userfullname: string;
59
+ created: number;
60
+ timemodified: number;
61
+ numreplies: number;
62
+ userid: number;
63
+ pinned: boolean;
64
+ attachment: boolean;
65
+ }
66
+ export interface ForumPost {
67
+ id: number;
68
+ subject: string;
69
+ /** El asunto que Moodle propone para responderla ("Re: ..."). */
70
+ replysubject: string;
71
+ message: string;
72
+ author: {
73
+ id: number;
74
+ fullname: string;
75
+ };
76
+ timecreated: number;
77
+ parentid: number | null;
78
+ isdeleted: boolean;
79
+ capabilities: {
80
+ reply: boolean;
81
+ edit: boolean;
82
+ delete: boolean;
83
+ };
84
+ attachments: {
85
+ filename: string;
86
+ fileurl: string;
87
+ filesize: number;
88
+ mimetype?: string;
89
+ }[];
90
+ }
91
+ export interface MoodleFile {
92
+ filename: string;
93
+ filepath?: string | null;
94
+ filesize: number;
95
+ fileurl: string;
96
+ mimetype?: string;
97
+ timemodified?: number | null;
98
+ }
99
+ /** Un plugin de entrega o de devolución: archivos (`fileareas`) o texto (`editorfields`). */
100
+ export interface AssignPlugin {
101
+ type: string;
102
+ name: string;
103
+ fileareas?: {
104
+ area: string;
105
+ files?: MoodleFile[];
106
+ }[];
107
+ editorfields?: {
108
+ name: string;
109
+ text: string;
110
+ format: number;
111
+ }[];
112
+ }
113
+ export interface AssignSubmission {
114
+ status: "new" | "draft" | "submitted" | "reopened" | string;
115
+ timemodified: number;
116
+ plugins?: AssignPlugin[];
117
+ }
118
+ export interface AssignSubmissionStatus {
119
+ lastattempt?: {
120
+ submission?: AssignSubmission;
121
+ /** En las entregas grupales la que cuenta es esta, no la individual. */
122
+ teamsubmission?: AssignSubmission;
123
+ locked: boolean;
124
+ graded: boolean;
125
+ canedit: boolean;
126
+ cansubmit: boolean;
127
+ extensionduedate: number | null;
128
+ gradingstatus: string;
129
+ };
130
+ feedback?: {
131
+ gradefordisplay?: string;
132
+ gradeddate?: number;
133
+ plugins?: AssignPlugin[];
134
+ };
135
+ }
136
+ export interface Assignment {
137
+ id: number;
138
+ cmid: number;
139
+ duedate: number;
140
+ cutoffdate: number;
141
+ allowsubmissionsfromdate: number;
142
+ /** 1: la entrega queda en borrador hasta que se confirma el envío. */
143
+ submissiondrafts: number;
144
+ requiresubmissionstatement: number;
145
+ /** HTML de la declaración que hay que aceptar al enviar; solo viene si se pide. */
146
+ submissionstatement?: string;
147
+ teamsubmission: number;
148
+ maxattempts: number;
149
+ configs: {
150
+ plugin: string;
151
+ subtype: string;
152
+ name: string;
153
+ value: string;
154
+ }[];
155
+ }
156
+ export interface Choice {
157
+ id: number;
158
+ coursemodule: number;
159
+ allowupdate: boolean;
160
+ allowmultiple: boolean;
161
+ timeopen: number;
162
+ timeclose: number;
163
+ }
164
+ export interface ChoiceOption {
165
+ id: number;
166
+ /** En choice es el texto de la opción; en choicegroup viene en `name`. */
167
+ text?: string;
168
+ name?: string;
169
+ maxanswers?: number;
170
+ countanswers?: number;
171
+ checked?: boolean;
172
+ disabled?: boolean;
173
+ }
@@ -0,0 +1,57 @@
1
+ import type { AulaSession } from "../client/session.js";
2
+ /**
3
+ * Con la dirección de un foro abre un hilo; con la de una discusión responde. Así el modelo no elige
4
+ * entre dos operaciones: la dirección que ya tiene dice cuál es.
5
+ */
6
+ export declare function postToForum(session: AulaSession, rawAddress: string, message: string, subject?: string, replyTo?: number): Promise<{
7
+ publicado: string;
8
+ direccion: string;
9
+ id?: undefined;
10
+ respuestaA?: undefined;
11
+ } | {
12
+ publicado: string;
13
+ direccion: string;
14
+ id: number;
15
+ respuestaA: number;
16
+ }>;
17
+ export declare function editForumPost(session: AulaSession, rawAddress: string, postId: number, message: string, subject?: string): Promise<{
18
+ editado: boolean;
19
+ direccion: string;
20
+ id: number;
21
+ }>;
22
+ export declare function deleteForumPost(session: AulaSession, rawAddress: string, postId: number): Promise<{
23
+ borrado: boolean;
24
+ id: number;
25
+ discusionBorrada: true | undefined;
26
+ direccion: string | undefined;
27
+ }>;
28
+ /** Deja elegidas exactamente `optionIds`; vacío borra la respuesta. Devuelve cómo quedó. */
29
+ export declare function answerChoice(session: AulaSession, rawAddress: string, optionIds: number[]): Promise<{
30
+ elegidas: number[];
31
+ aviso: string | undefined;
32
+ opciones: {
33
+ id: number;
34
+ texto: string | undefined;
35
+ elegida: true | undefined;
36
+ deshabilitada: true | undefined;
37
+ cupo: number | undefined;
38
+ anotados: number | undefined;
39
+ }[];
40
+ }>;
41
+ export declare function sendMessage(session: AulaSession, userId: number, message: string): Promise<{
42
+ enviado: boolean;
43
+ para: string;
44
+ }>;
45
+ export declare function addCalendarEvent(session: AulaSession, event: {
46
+ name: string;
47
+ start: string;
48
+ durationMinutes?: number;
49
+ description?: string;
50
+ }): Promise<{
51
+ creado: boolean;
52
+ id: number;
53
+ nombre: string;
54
+ inicio: string | null;
55
+ fin: string | null | undefined;
56
+ url: string;
57
+ }>;
@@ -0,0 +1,86 @@
1
+ import type { AulaSession } from "../client/session.js";
2
+ import type { ChoiceOption, CourseModule } from "../client/types.js";
3
+ /** La entrega del usuario (o la de su grupo): qué acepta la tarea, qué subió y la devolución si la hay. */
4
+ export declare function viewSubmission(session: AulaSession, courseId: number, module: CourseModule): Promise<{
5
+ estado: string;
6
+ grupal: true | undefined;
7
+ modificada: string | undefined;
8
+ abre: string | undefined;
9
+ vence: string | undefined;
10
+ prorroga: string | undefined;
11
+ cierreDefinitivo: string | undefined;
12
+ acepta: ({
13
+ tipo: string;
14
+ maximo: number | undefined;
15
+ tamanioMaximo: number | undefined;
16
+ extensiones: string | undefined;
17
+ limitePalabras?: undefined;
18
+ } | {
19
+ maximo?: undefined;
20
+ tamanioMaximo?: undefined;
21
+ extensiones?: undefined;
22
+ tipo: string;
23
+ limitePalabras: number | undefined;
24
+ })[] | undefined;
25
+ requiereConfirmarEnvio: true | undefined;
26
+ requiereDeclaracion: true | undefined;
27
+ declaracion: string | undefined;
28
+ puedeEditar: boolean;
29
+ puedeEnviar: true | undefined;
30
+ bloqueada: true | undefined;
31
+ devolucion: {
32
+ calificacion: string | undefined;
33
+ fecha: string | null;
34
+ archivos: {
35
+ nombre: string;
36
+ ruta: string | undefined;
37
+ tamanio: number;
38
+ mimetype: string | undefined;
39
+ modificado: string | null;
40
+ url: string;
41
+ }[] | undefined;
42
+ texto: string | undefined;
43
+ } | undefined;
44
+ archivos: {
45
+ nombre: string;
46
+ ruta: string | undefined;
47
+ tamanio: number;
48
+ mimetype: string | undefined;
49
+ modificado: string | null;
50
+ url: string;
51
+ }[] | undefined;
52
+ texto: string | undefined;
53
+ }>;
54
+ export declare function viewChoice(session: AulaSession, courseId: number, module: CourseModule): Promise<{
55
+ multiple: true | undefined;
56
+ puedeCambiar: boolean | undefined;
57
+ abre: string | undefined;
58
+ cierra: string | undefined;
59
+ opciones: {
60
+ id: number;
61
+ texto: string | undefined;
62
+ elegida: true | undefined;
63
+ deshabilitada: true | undefined;
64
+ cupo: number | undefined;
65
+ anotados: number | undefined;
66
+ }[];
67
+ }>;
68
+ /** El plugin no expone si deja cambiar o elegir varios grupos: eso lo dice la descripción o el error al elegir. */
69
+ export declare function viewChoicegroup(session: AulaSession, module: CourseModule): Promise<{
70
+ opciones: {
71
+ id: number;
72
+ texto: string | undefined;
73
+ elegida: true | undefined;
74
+ deshabilitada: true | undefined;
75
+ cupo: number | undefined;
76
+ anotados: number | undefined;
77
+ }[];
78
+ }>;
79
+ export declare function toOption(o: ChoiceOption): {
80
+ id: number;
81
+ texto: string | undefined;
82
+ elegida: true | undefined;
83
+ deshabilitada: true | undefined;
84
+ cupo: number | undefined;
85
+ anotados: number | undefined;
86
+ };
@@ -0,0 +1,36 @@
1
+ /**
2
+ * Direcciones de navegación del aula: un path que el modelo recibe en una respuesta
3
+ * y devuelve tal cual para entrar ahí. No hay estado en el servidor; la dirección
4
+ * dice todo lo necesario, y el padre se deduce del texto (eso es el "volver").
5
+ */
6
+ export declare const AddressLevel: {
7
+ readonly Root: "root";
8
+ readonly Course: "course";
9
+ readonly Module: "module";
10
+ readonly Discussion: "discussion";
11
+ };
12
+ export type AddressLevel = (typeof AddressLevel)[keyof typeof AddressLevel];
13
+ export type Address = {
14
+ level: "root";
15
+ } | {
16
+ level: "course";
17
+ courseId: number;
18
+ } | {
19
+ level: "module";
20
+ courseId: number;
21
+ cmid: number;
22
+ } | {
23
+ level: "discussion";
24
+ courseId: number;
25
+ cmid: number;
26
+ discussionId: number;
27
+ };
28
+ export declare const ROOT = "/";
29
+ export declare const courseAddr: (courseId: number) => string;
30
+ export declare const moduleAddr: (courseId: number, cmid: number) => string;
31
+ export declare const discussionAddr: (courseId: number, cmid: number, discussionId: number) => string;
32
+ export declare function parseAddress(raw: string): Address;
33
+ /** La dirección en texto, tal como la ve el modelo. */
34
+ export declare function formatAddress(address: Address): string;
35
+ /** La dirección de un nivel más arriba, o null si ya estamos en la raíz. */
36
+ export declare function parentOf(address: Address): string | null;
@@ -1,3 +1,14 @@
1
+ /**
2
+ * Direcciones de navegación del aula: un path que el modelo recibe en una respuesta
3
+ * y devuelve tal cual para entrar ahí. No hay estado en el servidor; la dirección
4
+ * dice todo lo necesario, y el padre se deduce del texto (eso es el "volver").
5
+ */
6
+ export const AddressLevel = {
7
+ Root: "root",
8
+ Course: "course",
9
+ Module: "module",
10
+ Discussion: "discussion",
11
+ };
1
12
  export const ROOT = "/";
2
13
  export const courseAddr = (courseId) => `/curso/${courseId}`;
3
14
  export const moduleAddr = (courseId, cmid) => `/curso/${courseId}/mod/${cmid}`;
@@ -0,0 +1,11 @@
1
+ import type { MoodleFile } from "../client/types.js";
2
+ /** Los timestamps de Moodle (segundos) en ISO; 0 o vacío es "sin fecha". */
3
+ export declare const isoDate: (seconds: number | null | undefined) => string | null;
4
+ export declare function toFile(f: MoodleFile): {
5
+ nombre: string;
6
+ ruta: string | undefined;
7
+ tamanio: number;
8
+ mimetype: string | undefined;
9
+ modificado: string | null;
10
+ url: string;
11
+ };
@@ -0,0 +1,32 @@
1
+ import { type Part } from "../../shared/documents/index.js";
2
+ import type { AulaSession } from "../client/session.js";
3
+ /** El más grande que hay hoy en los cursos pesa 12 MB. */
4
+ export declare const MAX_BYTES: number;
5
+ /**
6
+ * Moodle devuelve las URLs del web service, que piden token. Al usuario le sirve la misma ruta sin
7
+ * `/webservice`, que se abre con la sesión de su navegador. Es la única que mostramos: el token no
8
+ * sale nunca del servidor. `fileurl` viene de Moodle: ya es del aula del usuario.
9
+ */
10
+ export declare function userFacingUrl(fileurl: string): string;
11
+ /**
12
+ * Acepta cualquiera de las dos formas y devuelve la del web service. Solo archivos del aula del
13
+ * usuario (`baseUrl`): con cualquier otra URL estaríamos mandando su token a donde diga el modelo.
14
+ */
15
+ export declare function downloadUrl(baseUrl: string, url: string): URL;
16
+ /** Lo que ve el modelo de una lectura (las claves van en castellano) más las partes leídas. */
17
+ export interface FileRead {
18
+ archivo: string;
19
+ formato: string;
20
+ unidad: string;
21
+ total: number;
22
+ desde: number;
23
+ hasta: number;
24
+ /** El `desde` para pedir lo que sigue; no está si ya se leyó todo. */
25
+ siguiente?: number;
26
+ urlParaUsuario: string;
27
+ parts: (Part & {
28
+ number: number;
29
+ })[];
30
+ }
31
+ /** Baja un archivo del aula y devuelve desde la parte `from` tantas como entren en el presupuesto. */
32
+ export declare function readAulaFile(session: AulaSession, url: string, from?: number): Promise<FileRead>;
@@ -7,7 +7,7 @@ const BUDGET_CHARS = 30_000;
7
7
  /** Lo que cuesta una página como imagen (~1.600 tokens), medido en caracteres de texto. */
8
8
  const IMAGE_COST_CHARS = 6_000;
9
9
  /** El más grande que hay hoy en los cursos pesa 12 MB. */
10
- const MAX_BYTES = 30 * 1024 * 1024;
10
+ export const MAX_BYTES = 30 * 1024 * 1024;
11
11
  /**
12
12
  * Moodle devuelve las URLs del web service, que piden token. Al usuario le sirve la misma ruta sin
13
13
  * `/webservice`, que se abre con la sesión de su navegador. Es la única que mostramos: el token no
@@ -32,7 +32,7 @@ export function userFacingUrl(fileurl) {
32
32
  * Acepta cualquiera de las dos formas y devuelve la del web service. Solo archivos del aula del
33
33
  * usuario (`baseUrl`): con cualquier otra URL estaríamos mandando su token a donde diga el modelo.
34
34
  */
35
- function downloadUrl(baseUrl, url) {
35
+ export function downloadUrl(baseUrl, url) {
36
36
  let u;
37
37
  try {
38
38
  u = new URL(url);
@@ -0,0 +1,213 @@
1
+ import type { AulaSession } from "../client/session.js";
2
+ import type { CourseModule } from "../client/types.js";
3
+ /**
4
+ * Entra a una dirección del aula y devuelve su contenido, el padre y las direcciones de lo que hay
5
+ * adentro. Es el único lugar que decide qué ve el modelo y cuánto texto le cuesta.
6
+ */
7
+ export declare function open(session: AulaSession, rawAddress: string, page?: number): Promise<{
8
+ direccion: string;
9
+ padre: string | null;
10
+ cursos: {
11
+ direccion: string;
12
+ id: number;
13
+ nombre: string;
14
+ nombreCorto: string;
15
+ visible: boolean;
16
+ progreso: number | null;
17
+ ultimoAcceso: string | null;
18
+ }[];
19
+ } | {
20
+ direccion: string;
21
+ padre: string | null;
22
+ secciones: {
23
+ nombre: string;
24
+ numero: number;
25
+ resumen: string | undefined;
26
+ modulos: {
27
+ direccion: string;
28
+ id: number;
29
+ nombre: string;
30
+ tipo: string;
31
+ url: string | undefined;
32
+ descripcion: string | undefined;
33
+ restriccion: string | undefined;
34
+ fechas: {
35
+ etiqueta: string;
36
+ fecha: string | null;
37
+ }[] | undefined;
38
+ archivos: {
39
+ nombre: string;
40
+ ruta: string | undefined;
41
+ tamanio: number;
42
+ mimetype: string | undefined;
43
+ modificado: string | null;
44
+ url: string;
45
+ }[] | undefined;
46
+ enlaces: string[] | undefined;
47
+ }[];
48
+ }[];
49
+ } | {
50
+ direccion: string;
51
+ padre: string | null;
52
+ seccion: string;
53
+ modulo: {
54
+ direccion: string;
55
+ id: number;
56
+ nombre: string;
57
+ tipo: string;
58
+ url: string | undefined;
59
+ descripcion: string | undefined;
60
+ restriccion: string | undefined;
61
+ fechas: {
62
+ etiqueta: string;
63
+ fecha: string | null;
64
+ }[] | undefined;
65
+ archivos: {
66
+ nombre: string;
67
+ ruta: string | undefined;
68
+ tamanio: number;
69
+ mimetype: string | undefined;
70
+ modificado: string | null;
71
+ url: string;
72
+ }[] | undefined;
73
+ enlaces: string[] | undefined;
74
+ };
75
+ } | {
76
+ direccion: string;
77
+ padre: string | null;
78
+ seccion: string;
79
+ modulo: {
80
+ direccion: string;
81
+ id: number;
82
+ nombre: string;
83
+ tipo: string;
84
+ url: string | undefined;
85
+ descripcion: string | undefined;
86
+ restriccion: string | undefined;
87
+ fechas: {
88
+ etiqueta: string;
89
+ fecha: string | null;
90
+ }[] | undefined;
91
+ archivos: {
92
+ nombre: string;
93
+ ruta: string | undefined;
94
+ tamanio: number;
95
+ mimetype: string | undefined;
96
+ modificado: string | null;
97
+ url: string;
98
+ }[] | undefined;
99
+ enlaces: string[] | undefined;
100
+ };
101
+ entrega: {
102
+ estado: string;
103
+ grupal: true | undefined;
104
+ modificada: string | undefined;
105
+ abre: string | undefined;
106
+ vence: string | undefined;
107
+ prorroga: string | undefined;
108
+ cierreDefinitivo: string | undefined;
109
+ acepta: ({
110
+ tipo: string;
111
+ maximo: number | undefined;
112
+ tamanioMaximo: number | undefined;
113
+ extensiones: string | undefined;
114
+ limitePalabras?: undefined;
115
+ } | {
116
+ maximo?: undefined;
117
+ tamanioMaximo?: undefined;
118
+ extensiones?: undefined;
119
+ tipo: string;
120
+ limitePalabras: number | undefined;
121
+ })[] | undefined;
122
+ requiereConfirmarEnvio: true | undefined;
123
+ requiereDeclaracion: true | undefined;
124
+ declaracion: string | undefined;
125
+ puedeEditar: boolean;
126
+ puedeEnviar: true | undefined;
127
+ bloqueada: true | undefined;
128
+ devolucion: {
129
+ calificacion: string | undefined;
130
+ fecha: string | null;
131
+ archivos: {
132
+ nombre: string;
133
+ ruta: string | undefined;
134
+ tamanio: number;
135
+ mimetype: string | undefined;
136
+ modificado: string | null;
137
+ url: string;
138
+ }[] | undefined;
139
+ texto: string | undefined;
140
+ } | undefined;
141
+ archivos: {
142
+ nombre: string;
143
+ ruta: string | undefined;
144
+ tamanio: number;
145
+ mimetype: string | undefined;
146
+ modificado: string | null;
147
+ url: string;
148
+ }[] | undefined;
149
+ texto: string | undefined;
150
+ };
151
+ } | {
152
+ direccion: string;
153
+ padre: string | null;
154
+ seccion: string;
155
+ modulo: {
156
+ direccion: string;
157
+ id: number;
158
+ nombre: string;
159
+ tipo: string;
160
+ url: string | undefined;
161
+ descripcion: string | undefined;
162
+ restriccion: string | undefined;
163
+ fechas: {
164
+ etiqueta: string;
165
+ fecha: string | null;
166
+ }[] | undefined;
167
+ archivos: {
168
+ nombre: string;
169
+ ruta: string | undefined;
170
+ tamanio: number;
171
+ mimetype: string | undefined;
172
+ modificado: string | null;
173
+ url: string;
174
+ }[] | undefined;
175
+ enlaces: string[] | undefined;
176
+ };
177
+ eleccion: {
178
+ opciones: {
179
+ id: number;
180
+ texto: string | undefined;
181
+ elegida: true | undefined;
182
+ deshabilitada: true | undefined;
183
+ cupo: number | undefined;
184
+ anotados: number | undefined;
185
+ }[];
186
+ };
187
+ } | {
188
+ direccion: string;
189
+ padre: string | null;
190
+ asunto: string;
191
+ publicaciones: {
192
+ autor: string;
193
+ autorId: number;
194
+ fecha: string | null;
195
+ respuestaA: number | undefined;
196
+ id: number;
197
+ mensaje: string;
198
+ adjuntos: {
199
+ nombre: string;
200
+ ruta: string | undefined;
201
+ tamanio: number;
202
+ mimetype: string | undefined;
203
+ modificado: string | null;
204
+ url: string;
205
+ }[] | undefined;
206
+ acciones: (string | false)[] | undefined;
207
+ }[];
208
+ }>;
209
+ /** Ubica un módulo por su cmid y se queda con la sección que lo contiene. */
210
+ export declare function findModule(session: AulaSession, courseId: number, cmid: number): Promise<{
211
+ sectionName: string;
212
+ module: CourseModule;
213
+ }>;
@@ -0,0 +1,33 @@
1
+ import type { AulaSession } from "../client/session.js";
2
+ /**
3
+ * Escribe el pack sin pisar packs anteriores: nombre con fecha-hora y, si ya existe (dos packs
4
+ * en el mismo segundo), un sufijo -2, -3... La escritura es atómica por nombre (bandera "wx").
5
+ */
6
+ export declare function writePackFile(dir: string, courseName: string, bytes: Uint8Array): Promise<string>;
7
+ /**
8
+ * Baja PDF de un curso y los une en un solo archivo con índice, guardado en exportsDir().
9
+ * Con `archivos` une solo las URL pedidas (tal como las devuelve aula_open, validadas con
10
+ * `downloadUrl` como en aula_read_file); sin `archivos`, todos los PDF del curso. El pack sigue
11
+ * el orden del aula, no el de la lista, para que el índice acompañe las unidades. Los duplicados
12
+ * exactos se descartan al armar, porque ahí se bajan igual. Todo lo omitido queda listado en
13
+ * `omitidos` con el motivo; en el atajo sin `archivos`, los archivos que no son PDF solo se
14
+ * cuentan en `archivosNoPdf` en vez de listarse uno por uno.
15
+ */
16
+ export declare function buildStudyPack(session: AulaSession, rawAddress: string, archivos?: string[]): Promise<{
17
+ archivo: string;
18
+ curso: string;
19
+ paginas: number;
20
+ materiales: {
21
+ nombre: string;
22
+ seccion: string;
23
+ modulo: string;
24
+ paginas: number;
25
+ empiezaEn: number;
26
+ }[];
27
+ omitidos: {
28
+ nombre: string;
29
+ seccion: string;
30
+ motivo: string;
31
+ }[] | undefined;
32
+ archivosNoPdf: number | undefined;
33
+ }>;