sandbox-web-ide/backend/server/src/SecureGitClient.ts
2024-10-19 05:25:26 -06:00

85 lines
2.4 KiB
TypeScript

import fs from "fs"
import os from "os"
import path from "path"
import simpleGit, { SimpleGit } from "simple-git"
export type FileData = {
id: string
data: string
}
export class SecureGitClient {
private gitUrl: string
private sshKeyPath: string
constructor(gitUrl: string, sshKeyPath: string) {
this.gitUrl = gitUrl
this.sshKeyPath = sshKeyPath
}
async pushFiles(fileData: FileData[], repository: string): Promise<void> {
let tempDir: string | undefined
try {
// Create a temporary directory
tempDir = fs.mkdtempSync(path.posix.join(os.tmpdir(), "git-push-"))
console.log(`Temporary directory created: ${tempDir}`)
// Write files to the temporary directory
console.log(`Writing ${fileData.length} files.`)
for (const { id, data } of fileData) {
const filePath = path.posix.join(tempDir, id)
const dirPath = path.dirname(filePath)
if (!fs.existsSync(dirPath)) {
fs.mkdirSync(dirPath, { recursive: true })
}
fs.writeFileSync(filePath, data)
}
// Initialize the simple-git instance with the temporary directory and custom SSH command
const git: SimpleGit = simpleGit(tempDir, {
config: [
"core.sshCommand=ssh -i " +
this.sshKeyPath +
" -o IdentitiesOnly=yes",
],
}).outputHandler((_command, stdout, stderr) => {
stdout.pipe(process.stdout)
stderr.pipe(process.stderr)
})
// Initialize a new Git repository
await git.init()
// Add remote repository
await git.addRemote("origin", `${this.gitUrl}:${repository}`)
// Add files to the repository
for (const { id, data } of fileData) {
await git.add(id)
}
// Commit the changes
await git.commit("Add files.")
// Push the changes to the remote repository
await git.push("origin", "master", { "--force": null })
console.log("Files successfully pushed to the repository")
if (tempDir) {
fs.rmSync(tempDir, { recursive: true, force: true })
console.log(`Temporary directory removed: ${tempDir}`)
}
} catch (error) {
if (tempDir) {
fs.rmSync(tempDir, { recursive: true, force: true })
console.log(`Temporary directory removed: ${tempDir}`)
}
console.error("Error pushing files to the repository:", error)
throw error
}
}
}