( repoName: string, nodes: GraphNode[], links: GraphLink[], version: string = "1.0.0", extraMetadata?: Record<string, any> )
| 20 | } |
| 21 | |
| 22 | export async function packageCgcBundle( |
| 23 | repoName: string, |
| 24 | nodes: GraphNode[], |
| 25 | links: GraphLink[], |
| 26 | version: string = "1.0.0", |
| 27 | extraMetadata?: Record<string, any> |
| 28 | ): Promise<Blob> { |
| 29 | const zip = new JSZip(); |
| 30 | |
| 31 | // 1. Format nodes.jsonl |
| 32 | const nodesJsonl = nodes |
| 33 | .map(node => { |
| 34 | const labels = [node.type.toLowerCase()]; |
| 35 | const props = node.properties || {}; |
| 36 | return JSON.stringify({ |
| 37 | _id: Number(node.id) || node.id, |
| 38 | _labels: labels, |
| 39 | name: node.name, |
| 40 | type: node.type, |
| 41 | file: node.file || "", |
| 42 | val: node.val || 2, |
| 43 | ...props |
| 44 | }); |
| 45 | }) |
| 46 | .join("\n") + "\n"; |
| 47 | zip.file("nodes.jsonl", nodesJsonl); |
| 48 | |
| 49 | // 2. Format edges.jsonl |
| 50 | const edgesJsonl = links |
| 51 | .map((link, idx) => { |
| 52 | const fromId = typeof link.source === "object" ? link.source.id : link.source; |
| 53 | const toId = typeof link.target === "object" ? link.target.id : link.target; |
| 54 | return JSON.stringify({ |
| 55 | from: Number(fromId) || fromId, |
| 56 | to: Number(toId) || toId, |
| 57 | type: (link.type || "CONTAINS").toLowerCase(), |
| 58 | id: idx |
| 59 | }); |
| 60 | }) |
| 61 | .join("\n") + "\n"; |
| 62 | zip.file("edges.jsonl", edgesJsonl); |
| 63 | |
| 64 | // 3. Format metadata.json |
| 65 | let standardisedName = ""; |
| 66 | if (repoName.includes("/")) { |
| 67 | const owner = repoName.split('/')[0]; |
| 68 | const repo = repoName.split('/')[1]; |
| 69 | const branch = extraMetadata?.branch || "main"; |
| 70 | const commit = extraMetadata?.commit || extraMetadata?.version || version || "latest"; |
| 71 | const cleanCommit = commit.length === 40 && /^[0-9a-fA-F]+$/.test(commit) ? commit.substring(0, 7) : commit; |
| 72 | standardisedName = `${owner}__${repo}__${branch}__${cleanCommit}.cgc`; |
| 73 | } else { |
| 74 | standardisedName = `${repoName}.cgc`; |
| 75 | } |
| 76 | |
| 77 | // Extract and clean extraMetadata to prevent contaminating the strict standardized schema |
| 78 | const cleanExtra = { ...extraMetadata }; |
| 79 | delete cleanExtra.generator; |
no test coverage detected