diff --git a/LICENSE-THIRD-PARTY.md b/LICENSE-THIRD-PARTY.md index b686dbb..9cd0942 100644 --- a/LICENSE-THIRD-PARTY.md +++ b/LICENSE-THIRD-PARTY.md @@ -1,10 +1,8 @@ -Third Party Licenses -==================== +# Third Party Licenses -While Submitty VSCode is made available under the [BSD "3-Clause" License](https://github.com/Submitty/Submitty-VSCode/blob/master/LICENSE.md) +While Submitty VSCode is made available under the [BSD "3-Clause" License](https://github.com/Submitty/Submitty-VSCode/blob/master/LICENSE.md) we utilize several third-party libraries to help power various components. Below is a list of these components and their relevant copyrights, copied when the source was included/last updated within Submitty. - -| Component | Copyright | Url | License | -|--------------|----------------------------------------------------------------------|-----|---------| -| vscode-git | Copyright (c) Microsoft Corporation. All rights reserved. | https://code.visualstudio.com | [MIT License](https://github.com/microsoft/vscode/blob/main/LICENSE.txt) | \ No newline at end of file +| Component | Copyright | Url | License | +| ---------- | --------------------------------------------------------- | ----------------------------- | ------------------------------------------------------------------------ | +| vscode-git | Copyright (c) Microsoft Corporation. All rights reserved. | https://code.visualstudio.com | [MIT License](https://github.com/microsoft/vscode/blob/main/LICENSE.txt) | diff --git a/package-lock.json b/package-lock.json index 94411ee..eab1585 100644 --- a/package-lock.json +++ b/package-lock.json @@ -2839,6 +2839,7 @@ "integrity": "sha512-tsaTIkKW9b4N+AEj+SVA+WhJzV7/zMhcSu78mLKWSk7cXMOSHsBKFWUs0fWwq8QyK3MgJBQRX6Gbi4kYbdvGkQ==", "dev": true, "license": "MIT", + "license": "MIT", "dependencies": { "emoji-regex": "^10.3.0", "get-east-asian-width": "^1.0.0", diff --git a/src/services/apiService.ts b/src/services/apiService.ts index aad4b94..e3ef9d2 100644 --- a/src/services/apiService.ts +++ b/src/services/apiService.ts @@ -36,18 +36,27 @@ export class ApiService { this.client = new ApiClient(apiBaseUrl); } - // set token for local api client + /** + * Sets the authorization token for the API client. + * @param token - The bearer token for authenticated requests + */ setAuthorizationToken(token: string): void { this.client.setToken(token); } - // set base URL for local api client + /** + * Sets the base URL for the API client. + * @param baseUrl - The base URL of the Submitty API + */ setBaseUrl(baseUrl: string): void { this.client.setBaseURL(baseUrl); } /** - * Login to the Submitty API + * Logs in to the Submitty API and returns an auth token. + * @param userId - The user ID + * @param password - The user password + * @returns The authentication token */ async login(userId: string, password: string): Promise { try { @@ -71,6 +80,10 @@ export class ApiService { } } + /** + * Fetches the current authenticated user's profile from the API. + * @returns The current user data + */ async fetchMe(): Promise { try { const response = await this.client.get('/api/me'); @@ -83,20 +96,26 @@ export class ApiService { } /** - * Fetch all courses for the authenticated user + * Fetches all courses for the authenticated user. + * @returns The course list response */ - async fetchCourses(_token?: string): Promise { + async fetchCourses(): Promise { try { const response = await this.client.get('/api/courses'); return response.data; - } catch (error: unknown) { - console.error('Error fetching courses:', error); + } catch (error: any) { throw new Error(getErrorMessage(error, 'Failed to fetch courses.'), { cause: error, }); } } + /** + * Fetches all gradeables for a specific course. + * @param courseId - The course ID + * @param term - The term (e.g. "s24") + * @returns The gradeable list response + */ async fetchGradables( courseId: string, term: string @@ -114,7 +133,11 @@ export class ApiService { } /** - * Fetch grade details for a specific homework assignment + * Fetches grade details for a specific homework assignment. + * @param term - The term (e.g. "s24") + * @param courseId - The course ID + * @param gradeableId - The gradeable/assignment ID + * @returns The autograder details including test cases */ async fetchGradeDetails( term: string, @@ -136,9 +159,11 @@ export class ApiService { } /** - * Poll fetchGradeDetails until autograding_complete is true and test_cases has data. - * @param intervalMs Delay between requests (default 2000) - * @param timeoutMs Stop after this many ms (default 300000 = 5 min); 0 = no timeout + * Polls fetchGradeDetails until autograding is complete and test cases are available. + * @param term - The term (e.g. "s24") + * @param courseId - The course ID + * @param gradeableId - The gradeable/assignment ID + * @param options - Optional polling config: intervalMs (default 2000), timeoutMs (default 300000), token (cancellation) * @returns The final AutoGraderDetails with complete data */ async pollGradeDetailsUntilComplete( @@ -178,6 +203,13 @@ export class ApiService { } } + /** + * Submits a VCS (version control) gradable to trigger autograding. + * @param term - The term (e.g. "s24") + * @param courseId - The course ID + * @param gradeableId - The gradeable/assignment ID + * @returns The upload response + */ async submitVCSGradable( term: string, courseId: string, @@ -200,7 +232,11 @@ export class ApiService { } /** - * Fetch previous attempts for a specific homework assignment + * Fetches previous submission attempts for a specific homework assignment. + * @param term - The term (e.g. "s24") + * @param courseId - The course ID + * @param gradeableId - The gradeable/assignment ID + * @returns The list of previous attempts */ async fetchPreviousAttempts( term: string, @@ -220,6 +256,12 @@ export class ApiService { } } + /** + * Returns the singleton ApiService instance, creating it if necessary. + * @param context - The extension context + * @param apiBaseUrl - The base URL of the Submitty API + * @returns The ApiService instance + */ static getInstance( context: vscode.ExtensionContext, apiBaseUrl: string diff --git a/src/services/courseRepoResolver.ts b/src/services/courseRepoResolver.ts index 7ccffe5..d1f82d0 100644 --- a/src/services/courseRepoResolver.ts +++ b/src/services/courseRepoResolver.ts @@ -133,7 +133,7 @@ export class CourseRepoResolver { this.apiService.setAuthorizationToken(token); // Fetch courses and match based on whether their (term, courseId) strings appear in remote URLs. - const coursesResponse = await this.apiService.fetchCourses(token); + const coursesResponse = await this.apiService.fetchCourses(); const courses = coursesResponse.data.unarchived_courses; const remoteText = remoteUrls.join(' '); diff --git a/src/sidebar/login.html b/src/sidebar/login.html deleted file mode 100644 index b466d15..0000000 --- a/src/sidebar/login.html +++ /dev/null @@ -1,84 +0,0 @@ - - - - - - - -

Submitty Login

-
- - -
-
- - -
-
- - -
- -
- - - - diff --git a/src/sidebarContent.ts b/src/sidebarContent.ts index a16a84c..3842c4b 100644 --- a/src/sidebarContent.ts +++ b/src/sidebarContent.ts @@ -2,16 +2,6 @@ import * as vscode from 'vscode'; import * as path from 'path'; import * as fs from 'fs'; -export function getLoginHtml(context: vscode.ExtensionContext): string { - const filePath = path.join( - context.extensionPath, - 'src', - 'sidebar', - 'login.html' - ); - return fs.readFileSync(filePath, 'utf8'); -} - export function getClassesHtml(context: vscode.ExtensionContext): string { const filePath = path.join( context.extensionPath, diff --git a/src/sidebarProvider.ts b/src/sidebarProvider.ts index 173cdf4..7d7d0a7 100644 --- a/src/sidebarProvider.ts +++ b/src/sidebarProvider.ts @@ -75,13 +75,8 @@ export class SidebarProvider implements vscode.WebviewViewProvider { this.isLoadingCourses = true; try { - const token = await this.authService.getAuthorizationToken(); - if (!token) { - return; - } - this._view.webview.html = getClassesHtml(this.context); - await this.fetchAndDisplayCourses(token, this._view); + await this.fetchAndDisplayCourses(this._view); } catch (error: unknown) { const err = error instanceof Error ? error.message : String(error); console.error('Failed to load courses:', error); @@ -106,10 +101,7 @@ export class SidebarProvider implements vscode.WebviewViewProvider { switch (msg.command) { case MessageCommand.FETCH_AND_DISPLAY_COURSES: try { - const token = await this.authService.getAuthorizationToken(); - if (token) { - await this.fetchAndDisplayCourses(token, view); - } + await this.fetchAndDisplayCourses(view); } catch (error: unknown) { const err = error instanceof Error ? error.message : String(error); console.error('Failed to fetch and display courses:', error); @@ -157,11 +149,10 @@ export class SidebarProvider implements vscode.WebviewViewProvider { } private async fetchAndDisplayCourses( - token: string, view: vscode.WebviewView ): Promise { try { - const courses = await this.apiService.fetchCourses(token); + const courses = await this.apiService.fetchCourses(); const unarchived = courses.data.unarchived_courses; const coursesWithGradables = await Promise.all(