repoweaver
Version:
A GitHub App that skillfully weaves multiple templates together to create and update repositories with intelligent merge strategies
165 lines • 5.74 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.GitHubClient = void 0;
const auth_app_1 = require("@octokit/auth-app");
const rest_1 = require("@octokit/rest");
class GitHubClient {
constructor(appId, privateKey, installationId) {
this.installationId = installationId;
this.octokit = new rest_1.Octokit({
authStrategy: auth_app_1.createAppAuth,
auth: {
appId,
privateKey,
installationId,
},
});
}
async createRepository(name, description, isPrivate = false) {
const response = await this.octokit.rest.repos.createForAuthenticatedUser({
name,
description,
private: isPrivate,
auto_init: true,
});
return {
id: response.data.id,
owner: response.data.owner.login,
name: response.data.name,
fullName: response.data.full_name,
defaultBranch: response.data.default_branch,
isTemplate: response.data.is_template || false,
};
}
async getRepository(owner, name) {
const response = await this.octokit.rest.repos.get({
owner,
repo: name,
});
return {
id: response.data.id,
owner: response.data.owner.login,
name: response.data.name,
fullName: response.data.full_name,
defaultBranch: response.data.default_branch,
isTemplate: response.data.is_template || false,
};
}
async getRepositoryContents(owner, repo, path = '', ref) {
const response = await this.octokit.rest.repos.getContent({
owner,
repo,
path,
ref,
});
const items = Array.isArray(response.data) ? response.data : [response.data];
const files = [];
for (const item of items) {
if (item.type === 'file' && item.content) {
files.push({
name: item.name,
path: item.path,
content: Buffer.from(item.content, 'base64').toString('utf-8'),
type: 'file',
});
}
else if (item.type === 'dir') {
files.push({
name: item.name,
path: item.path,
content: '',
type: 'dir',
});
// Recursively get directory contents
const dirContents = await this.getRepositoryContents(owner, repo, item.path, ref);
files.push(...dirContents);
}
}
return files;
}
async createOrUpdateFile(owner, repo, path, content, message, branch) {
// Check if file exists
let sha;
try {
const existing = await this.octokit.rest.repos.getContent({
owner,
repo,
path,
ref: branch,
});
if (!Array.isArray(existing.data) && existing.data.type === 'file') {
sha = existing.data.sha;
}
}
catch (error) {
// File doesn't exist, which is fine
}
await this.octokit.rest.repos.createOrUpdateFileContents({
owner,
repo,
path,
message,
content: Buffer.from(content, 'utf-8').toString('base64'),
sha,
branch,
});
}
async createBranch(owner, repo, branchName, fromBranch) {
// Get the SHA of the base branch
const baseRef = fromBranch || 'main';
const baseBranchResponse = await this.octokit.rest.git.getRef({
owner,
repo,
ref: `heads/${baseRef}`,
});
// Create new branch
await this.octokit.rest.git.createRef({
owner,
repo,
ref: `refs/heads/${branchName}`,
sha: baseBranchResponse.data.object.sha,
});
}
async createPullRequest(owner, repo, title, body, head, base) {
const response = await this.octokit.rest.pulls.create({
owner,
repo,
title,
body,
head,
base,
});
return response.data.number;
}
async parseRepositoryUrl(url) {
// Parse GitHub repository URL
const match = url.match(/github\.com\/([^\/]+)\/([^\/]+?)(?:\.git)?(?:\/tree\/([^\/]+))?/);
if (!match) {
throw new Error(`Invalid GitHub repository URL: ${url}`);
}
return {
owner: match[1],
repo: match[2],
branch: match[3],
};
}
async getTemplateFiles(template) {
const { owner, repo, branch } = await this.parseRepositoryUrl(template.url);
const ref = template.branch || branch || 'main';
let files = await this.getRepositoryContents(owner, repo, '', ref);
// Filter out .git directory
files = files.filter((file) => !file.path.startsWith('.git'));
// If subDirectory is specified, filter to only include files from that directory
if (template.subDirectory) {
files = files.filter((file) => file.path.startsWith(template.subDirectory));
// Remove the subdirectory prefix from paths
files = files.map((file) => ({
...file,
path: file.path.replace(new RegExp(`^${template.subDirectory}/`), ''),
}));
}
return files;
}
}
exports.GitHubClient = GitHubClient;
//# sourceMappingURL=github-client.js.map