Files
gitea-mirror/src/lib/utils.ts
Arunavo Ray 38e0fb33b9 fix: resolve JSON parsing error and standardize HTTP client usage
- 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
2025-05-28 09:56:59 +05:30

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" },
});
};