feat: add download ZIP and push to GitHub features, fix code overflow in chat
This commit is contained in:
108
lib/artifact-utils.ts
Normal file
108
lib/artifact-utils.ts
Normal file
@@ -0,0 +1,108 @@
|
||||
import JSZip from "jszip";
|
||||
import { saveAs } from "file-saver";
|
||||
|
||||
export async function downloadArtifactAsZip(data: string, type: string, language: string = "html") {
|
||||
const zip = new JSZip();
|
||||
const extension = language === "html" || type === "web" || type === "app" ? "html" : (language === "typescript" || language === "tsx" ? "tsx" : "txt");
|
||||
const filename = `artifact-${Date.now()}.${extension}`;
|
||||
|
||||
// Check if data contains common multi-file structures (simple heuristic)
|
||||
// If it looks like a full project (multiple files defined in one block), we could parse it,
|
||||
// but for now we'll just save the main artifact.
|
||||
zip.file(filename, data);
|
||||
|
||||
// Add a basic README
|
||||
zip.file("README.md", `# AI Generated Artifact\n\nType: ${type}\nGenerated: ${new Date().toLocaleString()}`);
|
||||
|
||||
const content = await zip.generateAsync({ type: "blob" });
|
||||
saveAs(content, `promptarch-artifact-${Date.now()}.zip`);
|
||||
}
|
||||
|
||||
export async function pushToGithub(
|
||||
token: string,
|
||||
repoName: string,
|
||||
files: { path: string; content: string }[],
|
||||
description: string = "Generated by PromptArch"
|
||||
) {
|
||||
const headers = {
|
||||
'Authorization': `token ${token}`,
|
||||
'Accept': 'application/vnd.github.v3+json',
|
||||
'Content-Type': 'application/json',
|
||||
};
|
||||
|
||||
// 1. Check if repo exists, if not create it
|
||||
let repoData;
|
||||
const userResponse = await fetch('https://api.github.com/user', { headers });
|
||||
if (!userResponse.ok) throw new Error("Failed to authenticate with GitHub");
|
||||
const userData = await userResponse.json();
|
||||
const username = userData.login;
|
||||
|
||||
const repoCheckResponse = await fetch(`https://api.github.com/repos/${username}/${repoName}`, { headers });
|
||||
|
||||
if (repoCheckResponse.status === 404) {
|
||||
// Create repo
|
||||
const createResponse = await fetch('https://api.github.com/user/repos', {
|
||||
method: 'POST',
|
||||
headers,
|
||||
body: JSON.stringify({
|
||||
name: repoName,
|
||||
description,
|
||||
auto_init: true
|
||||
})
|
||||
});
|
||||
if (!createResponse.ok) throw new Error("Failed to create repository");
|
||||
repoData = await createResponse.json();
|
||||
// Wait a bit for repo to be ready
|
||||
await new Promise(resolve => setTimeout(resolve, 2000));
|
||||
} else {
|
||||
repoData = await repoCheckResponse.json();
|
||||
}
|
||||
|
||||
// 2. Get latest commit SHA of default branch
|
||||
const branchResponse = await fetch(`https://api.github.com/repos/${username}/${repoName}/branches/${repoData.default_branch}`, { headers });
|
||||
const branchData = await branchResponse.json();
|
||||
const latestCommitSha = branchData.commit.sha;
|
||||
|
||||
// 3. Create a new tree
|
||||
const treeItems = files.map(file => ({
|
||||
path: file.path,
|
||||
mode: '100644',
|
||||
type: 'blob',
|
||||
content: file.content
|
||||
}));
|
||||
|
||||
const treeResponse = await fetch(`https://api.github.com/repos/${username}/${repoName}/git/trees`, {
|
||||
method: 'POST',
|
||||
headers,
|
||||
body: JSON.stringify({
|
||||
base_tree: latestCommitSha,
|
||||
tree: treeItems
|
||||
})
|
||||
});
|
||||
const treeData = await treeResponse.json();
|
||||
|
||||
// 4. Create a new commit
|
||||
const commitResponse = await fetch(`https://api.github.com/repos/${username}/${repoName}/git/commits`, {
|
||||
method: 'POST',
|
||||
headers,
|
||||
body: JSON.stringify({
|
||||
message: `Update from PromptArch: ${new Date().toISOString()}`,
|
||||
tree: treeData.sha,
|
||||
parents: [latestCommitSha]
|
||||
})
|
||||
});
|
||||
const commitData = await commitResponse.json();
|
||||
|
||||
// 5. Update the reference
|
||||
const refResponse = await fetch(`https://api.github.com/repos/${username}/${repoName}/git/refs/heads/${repoData.default_branch}`, {
|
||||
method: 'PATCH',
|
||||
headers,
|
||||
body: JSON.stringify({
|
||||
sha: commitData.sha
|
||||
})
|
||||
});
|
||||
|
||||
if (!refResponse.ok) throw new Error("Failed to update branch reference");
|
||||
|
||||
return { url: repoData.html_url };
|
||||
}
|
||||
Reference in New Issue
Block a user