60 lines
1.7 KiB
TypeScript
60 lines
1.7 KiB
TypeScript
/**
|
|
* Provider factory — auto-detects GitHub vs GitLab vs Gitea from git remote.
|
|
*/
|
|
import type { IssueProvider } from "./provider.js";
|
|
import { GitLabProvider } from "./gitlab.js";
|
|
import { GitHubProvider } from "./github.js";
|
|
import { GiteaProvider } from "./gitea.js";
|
|
import { resolveRepoPath } from "../projects.js";
|
|
import { runCommand } from "../run-command.js";
|
|
|
|
export type ProviderOptions = {
|
|
provider?: "gitlab" | "github" | "gitea";
|
|
repo?: string;
|
|
repoPath?: string;
|
|
};
|
|
|
|
export type ProviderWithType = {
|
|
provider: IssueProvider;
|
|
type: "github" | "gitlab" | "gitea";
|
|
};
|
|
|
|
async function detectProvider(repoPath: string): Promise<"gitlab" | "github" | "gitea"> {
|
|
try {
|
|
const result = await runCommand(["git", "remote", "get-url", "origin"], { timeoutMs: 5_000, cwd: repoPath });
|
|
const remote = result.stdout.trim();
|
|
|
|
if (remote.includes("github.com")) {
|
|
return "github";
|
|
} else if (remote.includes("192.168.1.150:3000")) {
|
|
return "gitea";
|
|
} else {
|
|
return "gitlab";
|
|
}
|
|
} catch {
|
|
return "gitlab";
|
|
}
|
|
}
|
|
|
|
export async function createProvider(opts: ProviderOptions): Promise<ProviderWithType> {
|
|
const repoPath = opts.repoPath ?? (opts.repo ? resolveRepoPath(opts.repo) : null);
|
|
if (!repoPath) throw new Error("Either repoPath or repo must be provided");
|
|
const type = opts.provider ?? await detectProvider(repoPath);
|
|
|
|
let provider: IssueProvider;
|
|
switch (type) {
|
|
case "github":
|
|
provider = new GitHubProvider({ repoPath });
|
|
break;
|
|
case "gitea":
|
|
provider = new GiteaProvider({ repoPath });
|
|
break;
|
|
case "gitlab":
|
|
default:
|
|
provider = new GitLabProvider({ repoPath });
|
|
break;
|
|
}
|
|
|
|
return { provider, type };
|
|
}
|