hackages
Version:
CLI tool for learning software development concepts through test-driven development
113 lines (112 loc) • 3.63 kB
JavaScript
import axios from "axios";
import { config } from "../config/index.js";
import { printError } from "../utils/console.js";
import { getStoredAuth } from "./auth.js";
const api = axios.create({
baseURL: config.apiUrl,
headers: {
"Content-Type": "application/json",
},
});
// Add auth token to requests if available
api.interceptors.request.use((config) => {
const auth = getStoredAuth();
if (auth?.access_token && config.headers) {
config.headers.Authorization = `Bearer ${auth.access_token}`;
}
return config;
});
// Handle common error responses
api.interceptors.response.use((response) => response, (error) => {
if (error.response) {
const { status, data } = error.response;
const errorMessage = data?.error?.message || "An error occurred";
switch (status) {
case 401:
printError("Authentication required. Please run 'hackages login'");
break;
case 403:
printError("You don't have permission to perform this action");
break;
case 404:
printError("Resource not found");
break;
case 429:
printError("Too many requests. Please try again later");
break;
default:
printError(errorMessage);
}
}
else if (error.request) {
printError("No response from server. Please check your internet connection");
}
else {
printError(`Request error: ${error.message}`);
}
return Promise.reject(error);
});
export const apiClient = {
// Auth endpoints
auth: {
getAuthUrl: async () => {
try {
const response = await api.get("/api/auth/github");
return response.data;
}
catch (error) {
printError("Check your Internet connection and try again...");
throw error;
}
},
login: async (code) => {
const response = await api.post("/api/auth/github", { code });
return response.data;
},
getCurrentUser: async () => {
const response = await api.get("/api/auth/me");
return response.data;
},
},
// Exercise endpoints
exercises: {
generate: async (learningGoal) => {
const response = await api.post("/api/exercises/generate", { ...learningGoal });
return response.data;
},
review: async ({ topic, skillLevel, technology, sourceFiles }) => {
return await api.post("/api/exercises/review", {
sourceFiles,
technology,
skillLevel,
topic
});
},
},
// Technology endpoints
tech: {
getAllTechnologies: async () => {
const response = await api.get("/api/tech/config");
return response.data;
},
getTechnologyConfig: async (tech) => {
const response = await api.get(`/api/tech/config/${tech}`);
return response.data;
},
},
// Progress endpoints
progress: {
getProgress: async () => {
const response = await api.get("/api/progress");
return response.data;
},
updateProgress: async (exerciseId, status, score) => {
const response = await api.post("/api/progress/update", {
exerciseId,
status,
score,
});
return response.data;
},
},
};