mirror of
https://github.com/RayLabsHQ/gitea-mirror.git
synced 2025-12-06 19:46:44 +03:00
133 lines
3.7 KiB
TypeScript
133 lines
3.7 KiB
TypeScript
import type { APIRoute } from "astro";
|
|
import { Octokit } from "@octokit/rest";
|
|
import { configs, db, repositories } from "@/lib/db";
|
|
import { v4 as uuidv4 } from "uuid";
|
|
import { and, eq } from "drizzle-orm";
|
|
import { type Repository } from "@/lib/db/schema";
|
|
import { jsonResponse, createSecureErrorResponse } from "@/lib/utils";
|
|
import type {
|
|
AddRepositoriesApiRequest,
|
|
AddRepositoriesApiResponse,
|
|
RepositoryVisibility,
|
|
} from "@/types/Repository";
|
|
import { createMirrorJob } from "@/lib/helpers";
|
|
|
|
export const POST: APIRoute = async ({ request }) => {
|
|
try {
|
|
const body: AddRepositoriesApiRequest = await request.json();
|
|
const { owner, repo, userId } = body;
|
|
|
|
if (!owner || !repo || !userId) {
|
|
return new Response(
|
|
JSON.stringify({
|
|
success: false,
|
|
error: "Missing owner, repo, or userId",
|
|
}),
|
|
{ status: 400 }
|
|
);
|
|
}
|
|
|
|
// Check if repository with the same owner, name, and userId already exists
|
|
const existingRepo = await db
|
|
.select()
|
|
.from(repositories)
|
|
.where(
|
|
and(
|
|
eq(repositories.owner, owner),
|
|
eq(repositories.name, repo),
|
|
eq(repositories.userId, userId)
|
|
)
|
|
);
|
|
|
|
if (existingRepo.length > 0) {
|
|
return jsonResponse({
|
|
data: {
|
|
success: false,
|
|
error:
|
|
"Repository with this name and owner already exists for this user",
|
|
},
|
|
status: 400,
|
|
});
|
|
}
|
|
|
|
// Get user's active config
|
|
const [config] = await db
|
|
.select()
|
|
.from(configs)
|
|
.where(eq(configs.userId, userId))
|
|
.limit(1);
|
|
|
|
if (!config) {
|
|
return jsonResponse({
|
|
data: { error: "No configuration found for this user" },
|
|
status: 404,
|
|
});
|
|
}
|
|
|
|
const configId = config.id;
|
|
|
|
const octokit = new Octokit(); // No auth for public repos
|
|
|
|
const { data: repoData } = await octokit.rest.repos.get({ owner, repo });
|
|
|
|
const metadata = {
|
|
id: uuidv4(),
|
|
userId,
|
|
configId,
|
|
name: repoData.name,
|
|
fullName: repoData.full_name,
|
|
url: repoData.html_url,
|
|
cloneUrl: repoData.clone_url,
|
|
owner: repoData.owner.login,
|
|
organization:
|
|
repoData.owner.type === "Organization"
|
|
? repoData.owner.login
|
|
: undefined,
|
|
isPrivate: repoData.private,
|
|
isForked: repoData.fork,
|
|
forkedFrom: undefined,
|
|
hasIssues: repoData.has_issues,
|
|
isStarred: false,
|
|
isArchived: repoData.archived,
|
|
size: repoData.size,
|
|
hasLFS: false,
|
|
hasSubmodules: false,
|
|
defaultBranch: repoData.default_branch,
|
|
visibility: (repoData.visibility ?? "public") as RepositoryVisibility,
|
|
status: "imported" as Repository["status"],
|
|
lastMirrored: undefined,
|
|
errorMessage: undefined,
|
|
mirroredLocation: "",
|
|
createdAt: repoData.created_at
|
|
? new Date(repoData.created_at)
|
|
: new Date(),
|
|
updatedAt: repoData.updated_at
|
|
? new Date(repoData.updated_at)
|
|
: new Date(),
|
|
};
|
|
|
|
await db.insert(repositories).values(metadata);
|
|
|
|
createMirrorJob({
|
|
userId,
|
|
organizationId: metadata.organization,
|
|
organizationName: metadata.organization,
|
|
repositoryId: metadata.id,
|
|
repositoryName: metadata.name,
|
|
status: "imported",
|
|
message: `Repository ${metadata.name} fetched successfully`,
|
|
details: `Repository ${metadata.name} was fetched from GitHub`,
|
|
});
|
|
|
|
const resPayload: AddRepositoriesApiResponse = {
|
|
success: true,
|
|
repository: metadata,
|
|
message: "Repository added successfully",
|
|
};
|
|
|
|
return jsonResponse({ data: resPayload, status: 200 });
|
|
} catch (error) {
|
|
return createSecureErrorResponse(error, "repository sync", 500);
|
|
}
|
|
};
|