hackages
Version:
CLI tool for learning software development concepts through test-driven development
121 lines (120 loc) • 4.07 kB
JavaScript
import axios from "axios";
import { config } from "../config/index.js";
import { printError, formatError } 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
// Note: We don't print errors here to avoid duplicates - errors are handled by calling code
api.interceptors.response.use((response) => response, (error) => {
// Just reject the error - let the calling code handle user-friendly messages
return Promise.reject(error);
});
export const apiClient = {
// Auth endpoints
auth: {
checkCode: async (userHandle) => {
try {
// Always use production URL for the check endpoint
const response = await axios.post(`${config.apiUrl}/api/check`, {
userHandle,
});
return response.data;
}
catch (error) {
const friendlyMessage = formatError(error);
printError(`Unable to establish connection: ${friendlyMessage}`);
throw error;
}
},
getAuthUrl: async () => {
try {
const response = await api.get("/api/auth/github");
return response.data;
}
catch (error) {
const friendlyMessage = formatError(error);
printError(friendlyMessage);
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, exerciseNumber) => {
const response = await api.post("/api/exercises/generate", { ...learningGoal, exerciseNumber });
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;
},
},
// Learning endpoints
learning: {
getExercise: async (exerciseId) => {
const response = await api.get("/api/learning", {
params: { id: exerciseId },
});
return response.data;
},
getHint: async (learningGoalId, implementation, preferredLanguage) => {
const response = await api.post("/api/learning/hints", {
learningGoalId,
implementation,
preferredLanguage,
});
return response.data;
},
},
};