canvaslms-cli 1.4.6 → 1.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.
- package/CHANGELOG.md +18 -0
- package/README.md +32 -22
- package/dist/commands/announcements.d.ts +3 -0
- package/dist/commands/announcements.d.ts.map +1 -0
- package/dist/commands/announcements.js +92 -0
- package/dist/commands/announcements.js.map +1 -0
- package/dist/commands/api.d.ts +3 -0
- package/dist/commands/api.d.ts.map +1 -0
- package/dist/commands/api.js +8 -0
- package/dist/commands/api.js.map +1 -0
- package/dist/commands/assignments.d.ts +3 -0
- package/dist/commands/assignments.d.ts.map +1 -0
- package/dist/commands/assignments.js +100 -0
- package/dist/commands/assignments.js.map +1 -0
- package/dist/commands/config.d.ts +6 -0
- package/dist/commands/config.d.ts.map +1 -0
- package/dist/commands/config.js +202 -0
- package/dist/commands/config.js.map +1 -0
- package/dist/commands/grades.d.ts +3 -0
- package/dist/commands/grades.d.ts.map +1 -0
- package/dist/commands/grades.js +335 -0
- package/dist/commands/grades.js.map +1 -0
- package/dist/commands/list.d.ts +3 -0
- package/dist/commands/list.d.ts.map +1 -0
- package/dist/commands/list.js +61 -0
- package/dist/commands/list.js.map +1 -0
- package/dist/commands/profile.d.ts +6 -0
- package/dist/commands/profile.d.ts.map +1 -0
- package/dist/commands/profile.js +30 -0
- package/dist/commands/profile.js.map +1 -0
- package/dist/commands/submit.d.ts +8 -0
- package/dist/commands/submit.d.ts.map +1 -0
- package/dist/commands/submit.js +319 -0
- package/dist/commands/submit.js.map +1 -0
- package/dist/index.d.ts +15 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +15 -0
- package/dist/index.js.map +1 -0
- package/dist/lib/api-client.d.ts +2 -0
- package/dist/lib/api-client.d.ts.map +1 -0
- package/dist/lib/api-client.js +76 -0
- package/dist/lib/api-client.js.map +1 -0
- package/dist/lib/config-validator.d.ts +4 -0
- package/dist/lib/config-validator.d.ts.map +1 -0
- package/dist/lib/config-validator.js +38 -0
- package/dist/lib/config-validator.js.map +1 -0
- package/dist/lib/config.d.ts +10 -0
- package/dist/lib/config.d.ts.map +1 -0
- package/dist/lib/config.js +85 -0
- package/dist/lib/config.js.map +1 -0
- package/dist/lib/file-upload.d.ts +3 -0
- package/dist/lib/file-upload.d.ts.map +1 -0
- package/dist/lib/file-upload.js +52 -0
- package/dist/lib/file-upload.js.map +1 -0
- package/dist/lib/interactive.d.ts +16 -0
- package/dist/lib/interactive.d.ts.map +1 -0
- package/dist/lib/interactive.js +758 -0
- package/dist/lib/interactive.js.map +1 -0
- package/dist/src/index.d.ts +3 -0
- package/dist/src/index.d.ts.map +1 -0
- package/dist/src/index.js +90 -0
- package/dist/src/index.js.map +1 -0
- package/dist/types/index.d.ts +147 -0
- package/dist/types/index.d.ts.map +1 -0
- package/dist/types/index.js +2 -0
- package/dist/types/index.js.map +1 -0
- package/package.json +15 -15
- package/commands/announcements.js +0 -102
- package/commands/api.js +0 -19
- package/commands/assignments.js +0 -100
- package/commands/config.js +0 -239
- package/commands/grades.js +0 -201
- package/commands/list.js +0 -68
- package/commands/profile.js +0 -35
- package/commands/submit.js +0 -603
- package/lib/api-client.js +0 -75
- package/lib/config-validator.js +0 -60
- package/lib/config.js +0 -103
- package/lib/file-upload.js +0 -74
- package/lib/interactive.js +0 -889
- package/src/index.js +0 -120
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"config.js","sourceRoot":"","sources":["../../lib/config.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
export declare function uploadSingleFileToCanvas(courseId: number, assignmentId: number, filePath: string): Promise<number>;
|
|
2
|
+
export declare function submitAssignmentWithFiles(courseId: number, assignmentId: number, fileIds: number[]): Promise<any>;
|
|
3
|
+
//# sourceMappingURL=file-upload.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"file-upload.d.ts","sourceRoot":"","sources":["../../lib/file-upload.ts"],"names":[],"mappings":"AAcA,wBAAsB,wBAAwB,CAC5C,QAAQ,EAAE,MAAM,EAChB,YAAY,EAAE,MAAM,EACpB,QAAQ,EAAE,MAAM,GACf,OAAO,CAAC,MAAM,CAAC,CAuDjB;AAKD,wBAAsB,yBAAyB,CAC7C,QAAQ,EAAE,MAAM,EAChB,YAAY,EAAE,MAAM,EACpB,OAAO,EAAE,MAAM,EAAE,GAChB,OAAO,CAAC,GAAG,CAAC,CAcd"}
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
import fs from 'fs';
|
|
2
|
+
import path from 'path';
|
|
3
|
+
import axios from 'axios';
|
|
4
|
+
import FormData from 'form-data';
|
|
5
|
+
import { makeCanvasRequest } from './api-client.js';
|
|
6
|
+
export async function uploadSingleFileToCanvas(courseId, assignmentId, filePath) {
|
|
7
|
+
try {
|
|
8
|
+
if (!fs.existsSync(filePath)) {
|
|
9
|
+
throw new Error(`File not found: ${filePath}`);
|
|
10
|
+
}
|
|
11
|
+
const fileName = path.basename(filePath);
|
|
12
|
+
const fileContent = fs.readFileSync(filePath);
|
|
13
|
+
const uploadParams = [
|
|
14
|
+
`name=${fileName}`,
|
|
15
|
+
`size=${fileContent.length}`,
|
|
16
|
+
'parent_folder_path=/assignments'
|
|
17
|
+
];
|
|
18
|
+
const uploadData = await makeCanvasRequest('post', `courses/${courseId}/assignments/${assignmentId}/submissions/self/files`, uploadParams);
|
|
19
|
+
if (!uploadData.upload_url) {
|
|
20
|
+
throw new Error('Failed to get upload URL from Canvas');
|
|
21
|
+
}
|
|
22
|
+
const form = new FormData();
|
|
23
|
+
Object.keys(uploadData.upload_params).forEach(key => {
|
|
24
|
+
form.append(key, uploadData.upload_params[key]);
|
|
25
|
+
});
|
|
26
|
+
form.append('file', fileContent, fileName);
|
|
27
|
+
const uploadResponse = await axios.post(uploadData.upload_url, form, {
|
|
28
|
+
headers: form.getHeaders(),
|
|
29
|
+
maxRedirects: 0,
|
|
30
|
+
validateStatus: (status) => status < 400
|
|
31
|
+
});
|
|
32
|
+
const fileId = uploadData.id || uploadResponse.data.id;
|
|
33
|
+
if (typeof fileId !== 'number') {
|
|
34
|
+
throw new Error('Failed to get file ID from upload response');
|
|
35
|
+
}
|
|
36
|
+
return fileId;
|
|
37
|
+
}
|
|
38
|
+
catch (error) {
|
|
39
|
+
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
40
|
+
throw new Error(`Failed to upload file ${filePath}: ${errorMessage}`);
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
export async function submitAssignmentWithFiles(courseId, assignmentId, fileIds) {
|
|
44
|
+
const submissionData = {
|
|
45
|
+
submission: {
|
|
46
|
+
submission_type: 'online_upload',
|
|
47
|
+
file_ids: fileIds
|
|
48
|
+
}
|
|
49
|
+
};
|
|
50
|
+
return await makeCanvasRequest('post', `courses/${courseId}/assignments/${assignmentId}/submissions`, [], JSON.stringify(submissionData));
|
|
51
|
+
}
|
|
52
|
+
//# sourceMappingURL=file-upload.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"file-upload.js","sourceRoot":"","sources":["../../lib/file-upload.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,MAAM,IAAI,CAAC;AACpB,OAAO,IAAI,MAAM,MAAM,CAAC;AACxB,OAAO,KAAK,MAAM,OAAO,CAAC;AAC1B,OAAO,QAAQ,MAAM,WAAW,CAAC;AACjC,OAAO,EAAE,iBAAiB,EAAE,MAAM,iBAAiB,CAAC;AAMpD,MAAM,CAAC,KAAK,UAAU,wBAAwB,CAC5C,QAAgB,EAChB,YAAoB,EACpB,QAAgB;IAEhB,IAAI,CAAC;QAEH,IAAI,CAAC,EAAE,CAAC,UAAU,CAAC,QAAQ,CAAC,EAAE,CAAC;YAC7B,MAAM,IAAI,KAAK,CAAC,mBAAmB,QAAQ,EAAE,CAAC,CAAC;QACjD,CAAC;QAED,MAAM,QAAQ,GAAG,IAAI,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC;QACzC,MAAM,WAAW,GAAG,EAAE,CAAC,YAAY,CAAC,QAAQ,CAAC,CAAC;QAG9C,MAAM,YAAY,GAAG;YACnB,QAAQ,QAAQ,EAAE;YAClB,QAAQ,WAAW,CAAC,MAAM,EAAE;YAC5B,iCAAiC;SAClC,CAAC;QAEF,MAAM,UAAU,GAAG,MAAM,iBAAiB,CACxC,MAAM,EACN,WAAW,QAAQ,gBAAgB,YAAY,yBAAyB,EACxE,YAAY,CACb,CAAC;QAEF,IAAI,CAAC,UAAU,CAAC,UAAU,EAAE,CAAC;YAC3B,MAAM,IAAI,KAAK,CAAC,sCAAsC,CAAC,CAAC;QAC1D,CAAC;QAGD,MAAM,IAAI,GAAG,IAAI,QAAQ,EAAE,CAAC;QAG5B,MAAM,CAAC,IAAI,CAAC,UAAU,CAAC,aAAa,CAAC,CAAC,OAAO,CAAC,GAAG,CAAC,EAAE;YAClD,IAAI,CAAC,MAAM,CAAC,GAAG,EAAE,UAAU,CAAC,aAAa,CAAC,GAAG,CAAC,CAAC,CAAC;QAClD,CAAC,CAAC,CAAC;QAGH,IAAI,CAAC,MAAM,CAAC,MAAM,EAAE,WAAW,EAAE,QAAQ,CAAC,CAAC;QAE3C,MAAM,cAAc,GAAG,MAAM,KAAK,CAAC,IAAI,CAAC,UAAU,CAAC,UAAU,EAAE,IAAI,EAAE;YACnE,OAAO,EAAE,IAAI,CAAC,UAAU,EAAE;YAC1B,YAAY,EAAE,CAAC;YACf,cAAc,EAAE,CAAC,MAAM,EAAE,EAAE,CAAC,MAAM,GAAG,GAAG;SACzC,CAAC,CAAC;QAGH,MAAM,MAAM,GAAI,UAAkB,CAAC,EAAE,IAAI,cAAc,CAAC,IAAI,CAAC,EAAE,CAAC;QAChE,IAAI,OAAO,MAAM,KAAK,QAAQ,EAAE,CAAC;YAC/B,MAAM,IAAI,KAAK,CAAC,4CAA4C,CAAC,CAAC;QAChE,CAAC;QACD,OAAO,MAAM,CAAC;IAEhB,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,MAAM,YAAY,GAAG,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;QAC5E,MAAM,IAAI,KAAK,CAAC,yBAAyB,QAAQ,KAAK,YAAY,EAAE,CAAC,CAAC;IACxE,CAAC;AACH,CAAC;AAKD,MAAM,CAAC,KAAK,UAAU,yBAAyB,CAC7C,QAAgB,EAChB,YAAoB,EACpB,OAAiB;IAEjB,MAAM,cAAc,GAAG;QACrB,UAAU,EAAE;YACV,eAAe,EAAE,eAAe;YAChC,QAAQ,EAAE,OAAO;SAClB;KACF,CAAC;IAEF,OAAO,MAAM,iBAAiB,CAC5B,MAAM,EACN,WAAW,QAAQ,gBAAgB,YAAY,cAAc,EAC7D,EAAE,EACF,IAAI,CAAC,SAAS,CAAC,cAAc,CAAC,CAC/B,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import readline from 'readline';
|
|
2
|
+
interface AskConfirmationOptions {
|
|
3
|
+
requireExplicit?: boolean;
|
|
4
|
+
}
|
|
5
|
+
export declare function createReadlineInterface(): readline.Interface;
|
|
6
|
+
export declare function askQuestion(rl: readline.Interface, question: string): Promise<string>;
|
|
7
|
+
export declare function askQuestionWithValidation(rl: readline.Interface, question: string, validator: (input: string) => boolean, errorMessage?: string): Promise<string>;
|
|
8
|
+
export declare function askConfirmation(rl: readline.Interface, question: string, defaultYes?: boolean, options?: AskConfirmationOptions): Promise<boolean>;
|
|
9
|
+
export declare function selectFromList<T>(rl: readline.Interface, items: T[], displayProperty?: keyof T | null, allowCancel?: boolean): Promise<T | null>;
|
|
10
|
+
export declare function getSubfoldersRecursive(startDir?: string): string[];
|
|
11
|
+
export declare function getFilesMatchingWildcard(pattern: string, currentDir?: string): string[];
|
|
12
|
+
export declare function pad(str: string, len: number): string;
|
|
13
|
+
export declare function selectFilesImproved(rl: readline.Interface, currentDir?: string): Promise<string[]>;
|
|
14
|
+
export declare function selectFilesKeyboard(_rl: readline.Interface, currentDir?: string, allowedExtensions?: string[]): Promise<string[]>;
|
|
15
|
+
export {};
|
|
16
|
+
//# sourceMappingURL=interactive.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"interactive.d.ts","sourceRoot":"","sources":["../../lib/interactive.ts"],"names":[],"mappings":"AAIA,OAAO,QAAQ,MAAM,UAAU,CAAC;AA2BhC,UAAU,sBAAsB;IAC9B,eAAe,CAAC,EAAE,OAAO,CAAC;CAC3B;AAED,wBAAgB,uBAAuB,IAAI,QAAQ,CAAC,SAAS,CAK5D;AAED,wBAAgB,WAAW,CAAC,EAAE,EAAE,QAAQ,CAAC,SAAS,EAAE,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAMrF;AAED,wBAAgB,yBAAyB,CACvC,EAAE,EAAE,QAAQ,CAAC,SAAS,EACtB,QAAQ,EAAE,MAAM,EAChB,SAAS,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,OAAO,EACrC,YAAY,CAAC,EAAE,MAAM,GACpB,OAAO,CAAC,MAAM,CAAC,CAajB;AAKD,wBAAsB,eAAe,CACnC,EAAE,EAAE,QAAQ,CAAC,SAAS,EACtB,QAAQ,EAAE,MAAM,EAChB,UAAU,GAAE,OAAc,EAC1B,OAAO,GAAE,sBAA2B,GACnC,OAAO,CAAC,OAAO,CAAC,CAgClB;AAKD,wBAAsB,cAAc,CAAC,CAAC,EACpC,EAAE,EAAE,QAAQ,CAAC,SAAS,EACtB,KAAK,EAAE,CAAC,EAAE,EACV,eAAe,GAAE,MAAM,CAAC,GAAG,IAAW,EACtC,WAAW,GAAE,OAAc,GAC1B,OAAO,CAAC,CAAC,GAAG,IAAI,CAAC,CAoCnB;AAED,wBAAgB,sBAAsB,CAAC,QAAQ,GAAE,MAAsB,GAAG,MAAM,EAAE,CAqBjF;AAKD,wBAAgB,wBAAwB,CAAC,OAAO,EAAE,MAAM,EAAE,UAAU,GAAE,MAAsB,GAAG,MAAM,EAAE,CA2CtG;AAED,wBAAgB,GAAG,CAAC,GAAG,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG,MAAM,CAEpD;AAKD,wBAAsB,mBAAmB,CAAC,EAAE,EAAE,QAAQ,CAAC,SAAS,EAAE,UAAU,GAAE,MAAsB,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC,CAsLvH;AAKD,wBAAsB,mBAAmB,CACvC,GAAG,EAAE,QAAQ,CAAC,SAAS,EACvB,UAAU,GAAE,MAAsB,EAClC,iBAAiB,CAAC,EAAE,MAAM,EAAE,GAC3B,OAAO,CAAC,MAAM,EAAE,CAAC,CA8cnB"}
|