Skip to content
This repository has been archived by the owner on Oct 11, 2024. It is now read-only.

Commit

Permalink
refactor(util): use fetch instead of axios for HTTP requests (#68)
Browse files Browse the repository at this point in the history
* build(deps): remove axios

* refactor(http): use fetch instead of axios for HTTP requests
  • Loading branch information
frgfm authored Mar 22, 2024
1 parent 950a53a commit dc758b9
Show file tree
Hide file tree
Showing 4 changed files with 106 additions and 81 deletions.
1 change: 0 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -434,7 +434,6 @@
]
},
"dependencies": {
"axios": "^1.6.7",
"clipboardy": "^4.0.0",
"marked": "^12.0.0",
"node-machine-id": "^1.1.12",
Expand Down
27 changes: 11 additions & 16 deletions src/util/github.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@
// See LICENSE or go to <https://www.apache.org/licenses/LICENSE-2.0> for full license details.

import * as vscode from "vscode";
import axios, { AxiosResponse } from "axios";
import { getCurrentRepoName } from "./session";

export interface GitHubRepo {
Expand All @@ -25,19 +24,16 @@ interface GithubUser {
login: string;
}

export async function getUser(githubtoken: string): Promise<GithubUser> {
export async function getUser(githubToken: string): Promise<GithubUser> {
try {
// Check that it's a public repo
const response: AxiosResponse<any> = await axios.get(
`https://api.github.com/user`,
{
headers: { Authorization: `Bearer ${githubtoken}` },
},
);
const response = await fetch(`https://api.github.com/user`, {
headers: { Authorization: `Bearer ${githubToken}` },
});

// Handle the response
if (response.status === 200) {
return response.data;
if (response.ok) {
return (await response.json()) as GithubUser;
} else {
// The request returned a non-200 status code (e.g., 404)
// Show an error message or handle the error accordingly
Expand All @@ -64,14 +60,13 @@ export async function getRepoDetails(
): Promise<GitHubRepo> {
try {
// Check that it's a public repo
const response: AxiosResponse<any> = await axios.get(
`https://api.github.com/repos/${repoName}`,
{ headers: { Authorization: `Bearer ${githubToken}` } },
);
const response = await fetch(`https://api.github.com/repos/${repoName}`, {
headers: { Authorization: `Bearer ${githubToken}` },
});

// Handle the response
if (response.status === 200) {
return response.data;
if (response.ok) {
return (await response.json()) as GitHubRepo;
} else {
throw new Error(`GitHub API returned status code ${response.status}`);
}
Expand Down
157 changes: 94 additions & 63 deletions src/util/quack.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@
// See LICENSE or go to <https://www.apache.org/licenses/LICENSE-2.0> for full license details.

import * as vscode from "vscode";
import axios, { AxiosResponse, AxiosError } from "axios";

let config = vscode.workspace.getConfiguration("api");

Expand Down Expand Up @@ -40,6 +39,10 @@ export interface StreamingMessage {
done: boolean;
}

interface QuackToken {
access_token: string;
}

export async function verifyQuackEndpoint(
endpointURL: string,
): Promise<boolean> {
Expand All @@ -48,14 +51,15 @@ export async function verifyQuackEndpoint(
endpointURL,
).toString();
try {
await axios.get(routeURL);
return true;
} catch (error) {
if (error instanceof AxiosError) {
if (error.response && error.response.status === 401) {
return true;
}
const response = await fetch(routeURL);
if (response.ok) {
return true;
} else if (response.status === 401) {
return true;
} else {
return false;
}
} catch (error) {
return false;
}
}
Expand All @@ -69,19 +73,21 @@ export async function getAPIAccessStatus(
endpointURL,
).toString();
try {
await axios.get(routeURL, {
const response = await fetch(routeURL, {
headers: { Authorization: `Bearer ${quackToken}` },
});
return "ok"; // Token & endpoint good
if (response.ok) {
return "ok"; // Token & endpoint good
} else if (response.status === 404) {
return "unknown-route"; // Unknown route
} else if (response.status === 401) {
return "expired-token"; // Expired token
} else {
return "other"; // Other HTTP status codes
}
} catch (error) {
if (error instanceof AxiosError) {
if (error.code === "ECONNREFUSED") {
return "unreachable-endpoint"; // Wrong endpoint
} else if (error.response && error.response.status === 404) {
return "unknown-route"; // Unknown route
} else if (error.response && error.response.status === 401) {
return "expired-token"; // expired
}
if (error instanceof Error && error.name === "TypeError") {
return "unreachable-endpoint"; // Wrong endpoint
}
return "other"; // Token or server issues
}
Expand Down Expand Up @@ -115,13 +121,20 @@ export async function getToken(
const quackURL = new URL("/api/v1/login/token", endpointURL).toString();
try {
// Retrieve the guidelines
const response: AxiosResponse<any> = await axios.post(quackURL, {
github_token: githubToken,
const response = await fetch(quackURL, {
method: "POST",
headers: {
"Content-Type": "application/json",
},
body: JSON.stringify({
github_token: githubToken,
}),
});

// Handle the response
if (response.status === 200) {
return response.data.access_token;
if (response.ok) {
const data = (await response.json()) as QuackToken;
return data.access_token;
} else {
// The request returned a non-200 status code (e.g., 404)
// Show an error message or handle the error accordingly
Expand Down Expand Up @@ -149,13 +162,13 @@ export async function fetchGuidelines(
const quackURL = new URL(`/api/v1/guidelines`, endpointURL).toString();
try {
// Retrieve the guidelines
const response: AxiosResponse<any> = await axios.get(quackURL, {
const response = await fetch(quackURL, {
headers: { Authorization: `Bearer ${token}` },
});

// Handle the response
if (response.status === 200) {
return response.data;
if (response.ok) {
return (await response.json()) as QuackGuideline[];
} else {
// The request returned a non-200 status code (e.g., 404)
// Show an error message or handle the error accordingly
Expand Down Expand Up @@ -185,24 +198,36 @@ export async function postChatMessage(
): Promise<void> {
const quackURL = new URL("/api/v1/code/chat", endpointURL).toString();
try {
const response: AxiosResponse<any> = await axios.post(
quackURL,
{ messages: messages },
{ headers: { Authorization: `Bearer ${token}` }, responseType: "stream" },
);
response.data.on("data", (chunk: any) => {
// Handle the chunk of data
onChunkReceived(JSON.parse(chunk).message.content);
});

response.data.on("end", () => {
// console.log("Stream ended");
onEnd();
const response = await fetch(quackURL, {
method: "POST",
headers: {
"Content-Type": "application/json",
Authorization: `Bearer ${token}`,
},
body: JSON.stringify({ messages: messages }),
});

response.data.on("error", (error: Error) => {
console.error(error);
});
if (response.body) {
const reader = response.body.getReader();
try {
while (true) {
const { done, value } = await reader.read();
if (done) {
break;
}
// Assume each chunk is a Uint8Array, convert to a string or otherwise process
const chunk = new TextDecoder().decode(value);
// Process the chunk, e.g., assuming JSON content
onChunkReceived(JSON.parse(chunk).message.content);
}
// Stream ended
onEnd();
} catch (error) {
console.error(error);
} finally {
reader.releaseLock();
}
}
} catch (error) {
// Handle other errors that may occur during the request
console.error("Error sending Quack API request:", error);
Expand All @@ -219,17 +244,18 @@ export async function postGuideline(
const quackURL = new URL(`/api/v1/guidelines`, endpointURL).toString();
try {
// Retrieve the guidelines
const response: AxiosResponse<any> = await axios.post(
quackURL,
{ content: content },
{
headers: { Authorization: `Bearer ${token}` },
const response = await fetch(quackURL, {
method: "POST",
headers: {
"Content-Type": "application/json",
Authorization: `Bearer ${token}`,
},
);
body: JSON.stringify({ content: content }),
});

// Handle the response
if (response.status === 201) {
return response.data;
if (response.ok) {
return (await response.json()) as QuackGuideline;
} else {
vscode.window.showErrorMessage(
`Quack API returned status code ${response.status}`,
Expand All @@ -254,18 +280,19 @@ export async function patchGuideline(
): Promise<QuackGuideline> {
const quackURL = new URL(`/api/v1/guidelines/${id}`, endpointURL).toString();
try {
// Retrieve the guidelines
const response: AxiosResponse<any> = await axios.patch(
quackURL,
{ content: content },
{
headers: { Authorization: `Bearer ${token}` },
// Update the guideline
const response = await fetch(quackURL, {
method: "PATCH",
headers: {
"Content-Type": "application/json",
Authorization: `Bearer ${token}`,
},
);
body: JSON.stringify({ content: content }),
});

// Handle the response
if (response.status === 200) {
return response.data;
if (response.ok) {
return (await response.json()) as QuackGuideline;
} else {
vscode.window.showErrorMessage(
`Quack API returned status code ${response.status}`,
Expand All @@ -289,14 +316,18 @@ export async function deleteGuideline(
): Promise<QuackGuideline> {
const quackURL = new URL(`/api/v1/guidelines/${id}`, endpointURL).toString();
try {
// Retrieve the guidelines
const response: AxiosResponse<any> = await axios.delete(quackURL, {
headers: { Authorization: `Bearer ${token}` },
// Delete the guideline
const response = await fetch(quackURL, {
method: "DELETE",
headers: {
"Content-Type": "application/json",
Authorization: `Bearer ${token}`,
},
});

// Handle the response
if (response.status === 200) {
return response.data;
if (response.ok) {
return (await response.json()) as QuackGuideline;
} else {
vscode.window.showErrorMessage(
`Quack API returned status code ${response.status}`,
Expand Down
2 changes: 1 addition & 1 deletion yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -494,7 +494,7 @@ asynckit@^0.4.0:
resolved "https://registry.yarnpkg.com/asynckit/-/asynckit-0.4.0.tgz#c79ed97f7f34cb8f2ba1bc9790bcc366474b4b79"
integrity sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==

axios@^1.6.2, axios@^1.6.7:
axios@^1.6.2:
version "1.6.7"
resolved "https://registry.yarnpkg.com/axios/-/axios-1.6.7.tgz#7b48c2e27c96f9c68a2f8f31e2ab19f59b06b0a7"
integrity sha512-/hDJGff6/c7u0hDkvkGxR/oy6CbCs8ziCsC7SqmhjfozqiJGc8Z11wrv9z9lYfY4K8l+H9TpjcMDX0xOZmx+RA==
Expand Down

0 comments on commit dc758b9

Please sign in to comment.