🎉 Gitea Mirror: Added

This commit is contained in:
Arunavo Ray
2025-05-18 09:31:23 +05:30
commit 5d40023de0
139 changed files with 22033 additions and 0 deletions

View File

@@ -0,0 +1,60 @@
import type { APIRoute } from "astro";
import { db } from "@/lib/db";
import { organizations } from "@/lib/db";
import { eq, sql } from "drizzle-orm";
import {
membershipRoleEnum,
type OrganizationsApiResponse,
} from "@/types/organizations";
import type { Organization } from "@/lib/db/schema";
import { repoStatusEnum } from "@/types/Repository";
import { jsonResponse } from "@/lib/utils";
export const GET: APIRoute = async ({ request }) => {
const url = new URL(request.url);
const userId = url.searchParams.get("userId");
if (!userId) {
return jsonResponse({
data: {
success: false,
error: "Missing userId",
},
status: 400,
});
}
try {
const rawOrgs = await db
.select()
.from(organizations)
.where(eq(organizations.userId, userId))
.orderBy(sql`name COLLATE NOCASE`);
const orgsWithIds: Organization[] = rawOrgs.map((org) => ({
...org,
status: repoStatusEnum.parse(org.status),
membershipRole: membershipRoleEnum.parse(org.membershipRole),
lastMirrored: org.lastMirrored ?? undefined,
errorMessage: org.errorMessage ?? undefined,
}));
const resPayload: OrganizationsApiResponse = {
success: true,
message: "Organizations fetched successfully",
organizations: orgsWithIds,
};
return jsonResponse({ data: resPayload, status: 200 });
} catch (error) {
console.error("Error fetching organizations:", error);
return jsonResponse({
data: {
success: false,
error: error instanceof Error ? error.message : "Something went wrong",
},
status: 500,
});
}
};

View File

@@ -0,0 +1,96 @@
import type { APIRoute } from "astro";
import { db, repositories, configs } from "@/lib/db";
import { and, eq, sql } from "drizzle-orm";
import {
repositoryVisibilityEnum,
repoStatusEnum,
type RepositoryApiResponse,
} from "@/types/Repository";
import { jsonResponse } from "@/lib/utils";
export const GET: APIRoute = async ({ request }) => {
const url = new URL(request.url);
const userId = url.searchParams.get("userId");
if (!userId) {
return jsonResponse({
data: { success: false, error: "Missing userId" },
status: 400,
});
}
try {
// Fetch the user's active configuration
const [config] = await db
.select()
.from(configs)
.where(and(eq(configs.userId, userId), eq(configs.isActive, true)));
if (!config) {
return jsonResponse({
data: {
success: false,
error: "No active configuration found for this user",
},
status: 404,
});
}
const githubConfig = config.githubConfig as {
mirrorStarred: boolean;
skipForks: boolean;
privateRepositories: boolean;
};
// Build query conditions based on config
const conditions = [eq(repositories.userId, userId)];
if (!githubConfig.mirrorStarred) {
conditions.push(eq(repositories.isStarred, false));
}
if (githubConfig.skipForks) {
conditions.push(eq(repositories.isForked, false));
}
if (!githubConfig.privateRepositories) {
conditions.push(eq(repositories.isPrivate, false));
}
const rawRepositories = await db
.select()
.from(repositories)
.where(and(...conditions))
.orderBy(sql`name COLLATE NOCASE`);
const response: RepositoryApiResponse = {
success: true,
message: "Repositories fetched successfully",
repositories: rawRepositories.map((repo) => ({
...repo,
organization: repo.organization ?? undefined,
lastMirrored: repo.lastMirrored ?? undefined,
errorMessage: repo.errorMessage ?? undefined,
forkedFrom: repo.forkedFrom ?? undefined,
status: repoStatusEnum.parse(repo.status),
visibility: repositoryVisibilityEnum.parse(repo.visibility),
})),
};
return jsonResponse({
data: response,
status: 200,
});
} catch (error) {
console.error("Error fetching repositories:", error);
return jsonResponse({
data: {
success: false,
error: error instanceof Error ? error.message : "Something went wrong",
message: "An error occurred while fetching repositories.",
},
status: 500,
});
}
};

View File

@@ -0,0 +1,101 @@
import type { APIRoute } from "astro";
import { Octokit } from "@octokit/rest";
export const POST: APIRoute = async ({ request }) => {
try {
const body = await request.json();
const { token, username } = body;
if (!token) {
return new Response(
JSON.stringify({
success: false,
message: "GitHub token is required",
}),
{
status: 400,
headers: {
"Content-Type": "application/json",
},
}
);
}
// Create an Octokit instance with the provided token
const octokit = new Octokit({
auth: token,
});
// Test the connection by fetching the authenticated user
const { data } = await octokit.users.getAuthenticated();
// Verify that the authenticated user matches the provided username (if provided)
if (username && data.login !== username) {
return new Response(
JSON.stringify({
success: false,
message: `Token belongs to ${data.login}, not ${username}`,
}),
{
status: 400,
headers: {
"Content-Type": "application/json",
},
}
);
}
// Return success response with user data
return new Response(
JSON.stringify({
success: true,
message: `Successfully connected to GitHub as ${data.login}`,
user: {
login: data.login,
name: data.name,
avatar_url: data.avatar_url,
},
}),
{
status: 200,
headers: {
"Content-Type": "application/json",
},
}
);
} catch (error) {
console.error("GitHub connection test failed:", error);
// Handle specific error types
if (error instanceof Error && (error as any).status === 401) {
return new Response(
JSON.stringify({
success: false,
message: "Invalid GitHub token",
}),
{
status: 401,
headers: {
"Content-Type": "application/json",
},
}
);
}
// Generic error response
return new Response(
JSON.stringify({
success: false,
message: `GitHub connection test failed: ${
error instanceof Error ? error.message : "Unknown error"
}`,
}),
{
status: 500,
headers: {
"Content-Type": "application/json",
},
}
);
}
};