mirror of
https://github.com/RayLabsHQ/gitea-mirror.git
synced 2025-12-07 03:56:46 +03:00
- Fix JSON parsing error in getOrCreateGiteaOrg function (#19) - Add content-type validation before JSON parsing - Add response cloning for better error debugging - Enhance error messages with actual response content - Add comprehensive logging for troubleshooting - Standardize HTTP client usage across codebase - Create new http-client.ts utility with consistent error handling - Replace all superagent calls with fetch-based functions - Replace all axios calls with fetch-based functions - Remove superagent, axios, and @types/superagent dependencies - Update tests to mock new HTTP client - Maintain backward compatibility - Benefits: - Smaller bundle size (removed 3 HTTP client libraries) - Better performance (leveraging Bun's optimized fetch) - Consistent error handling across all HTTP operations - Improved debugging with detailed error messages - Easier maintenance with single HTTP client pattern
98 lines
2.2 KiB
TypeScript
98 lines
2.2 KiB
TypeScript
import { clsx, type ClassValue } from "clsx";
|
|
import { twMerge } from "tailwind-merge";
|
|
import { httpRequest, HttpError } from "@/lib/http-client";
|
|
import type { RepoStatus } from "@/types/Repository";
|
|
|
|
export const API_BASE = "/api";
|
|
|
|
export function cn(...inputs: ClassValue[]) {
|
|
return twMerge(clsx(inputs));
|
|
}
|
|
|
|
export function formatDate(date?: Date | string | null): string {
|
|
if (!date) return "Never";
|
|
return new Intl.DateTimeFormat("en-US", {
|
|
year: "numeric",
|
|
month: "long",
|
|
day: "numeric",
|
|
hour: "2-digit",
|
|
minute: "2-digit",
|
|
}).format(new Date(date));
|
|
}
|
|
|
|
export function truncate(str: string, length: number): string {
|
|
if (str.length <= length) return str;
|
|
return str.slice(0, length) + "...";
|
|
}
|
|
|
|
export function safeParse<T>(value: unknown): T | undefined {
|
|
if (typeof value === "string") {
|
|
try {
|
|
return JSON.parse(value) as T;
|
|
} catch {
|
|
return undefined;
|
|
}
|
|
}
|
|
return value as T;
|
|
}
|
|
|
|
// Helper function for API requests
|
|
|
|
export async function apiRequest<T>(
|
|
endpoint: string,
|
|
options: RequestInit = {}
|
|
): Promise<T> {
|
|
try {
|
|
const response = await httpRequest<T>(`${API_BASE}${endpoint}`, {
|
|
headers: {
|
|
"Content-Type": "application/json",
|
|
...(options.headers || {}),
|
|
},
|
|
...options,
|
|
});
|
|
|
|
return response.data;
|
|
} catch (err) {
|
|
const error = err as HttpError;
|
|
|
|
const message =
|
|
error.response ||
|
|
error.message ||
|
|
"An unknown error occurred";
|
|
|
|
throw new Error(message);
|
|
}
|
|
}
|
|
|
|
export const getStatusColor = (status: RepoStatus): string => {
|
|
switch (status) {
|
|
case "imported":
|
|
return "bg-blue-500"; // Info/primary-like
|
|
case "mirroring":
|
|
return "bg-yellow-400"; // In progress
|
|
case "mirrored":
|
|
return "bg-emerald-500"; // Success
|
|
case "failed":
|
|
return "bg-rose-500"; // Error
|
|
case "syncing":
|
|
return "bg-indigo-500"; // Sync in progress
|
|
case "synced":
|
|
return "bg-teal-500"; // Sync complete
|
|
default:
|
|
return "bg-gray-400"; // Unknown/neutral
|
|
}
|
|
};
|
|
|
|
export const jsonResponse = ({
|
|
data,
|
|
status = 200,
|
|
}: {
|
|
data: unknown;
|
|
status?: number;
|
|
}): Response => {
|
|
return new Response(JSON.stringify(data), {
|
|
status,
|
|
headers: { "Content-Type": "application/json" },
|
|
});
|
|
};
|