You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
111 lines
3.4 KiB
111 lines
3.4 KiB
import { readFileSync } from 'fs'; |
|
import { finalizeEvent } from 'nostr-tools'; |
|
import { decode } from 'nostr-tools/nip19'; |
|
import { publishEventCommon, addClientTag } from './index.js'; |
|
|
|
/** |
|
* Publish patch |
|
*/ |
|
export async function publishPatch(args, relays, privateKeyBytes, pubkey, json) { |
|
const [ownerNpub, repoName, patchFile] = args; |
|
if (!ownerNpub || !repoName || !patchFile) { |
|
console.error('Error: owner npub, repo name, and patch file required'); |
|
console.error('Use: publish patch <owner-npub> <repo> <patch-file> [options]'); |
|
console.error('Note: Patch file should be generated with: git format-patch'); |
|
process.exit(1); |
|
} |
|
|
|
let ownerPubkey; |
|
try { |
|
ownerPubkey = ownerNpub.startsWith('npub') ? decode(ownerNpub).data : ownerNpub; |
|
if (ownerPubkey instanceof Uint8Array) { |
|
ownerPubkey = Array.from(ownerPubkey).map(b => b.toString(16).padStart(2, '0')).join(''); |
|
} |
|
} catch (err) { |
|
throw new Error(`Invalid npub format: ${err.message}`); |
|
} |
|
|
|
// Read patch file |
|
let patchContent; |
|
try { |
|
patchContent = readFileSync(patchFile, 'utf-8'); |
|
} catch (err) { |
|
throw new Error(`Failed to read patch file: ${err.message}`); |
|
} |
|
|
|
const repoAddress = `30617:${ownerPubkey}:${repoName}`; |
|
const tags = [ |
|
['a', repoAddress], |
|
['p', ownerPubkey] |
|
]; |
|
|
|
// Parse options |
|
let earliestCommit = null; |
|
let commitId = null; |
|
let parentCommit = null; |
|
let isRoot = false; |
|
let isRootRevision = false; |
|
const mentions = []; |
|
|
|
for (let i = 3; i < args.length; i++) { |
|
if (args[i] === '--earliest-commit' && args[i + 1]) { |
|
earliestCommit = args[++i]; |
|
tags.push(['r', earliestCommit]); |
|
} else if (args[i] === '--commit' && args[i + 1]) { |
|
commitId = args[++i]; |
|
tags.push(['commit', commitId]); |
|
tags.push(['r', commitId]); |
|
} else if (args[i] === '--parent-commit' && args[i + 1]) { |
|
parentCommit = args[++i]; |
|
tags.push(['parent-commit', parentCommit]); |
|
} else if (args[i] === '--root') { |
|
isRoot = true; |
|
tags.push(['t', 'root']); |
|
} else if (args[i] === '--root-revision') { |
|
isRootRevision = true; |
|
tags.push(['t', 'root-revision']); |
|
} else if (args[i] === '--mention' && args[i + 1]) { |
|
mentions.push(args[++i]); |
|
} else if (args[i] === '--reply-to' && args[i + 1]) { |
|
// NIP-10 reply tag |
|
tags.push(['e', args[++i], '', 'reply']); |
|
} |
|
} |
|
|
|
// Add earliest commit if provided |
|
if (earliestCommit) { |
|
tags.push(['r', earliestCommit, 'euc']); |
|
} |
|
|
|
// Add mentions |
|
for (const mention of mentions) { |
|
let mentionPubkey = mention; |
|
try { |
|
if (mention.startsWith('npub')) { |
|
mentionPubkey = decode(mention).data; |
|
if (mentionPubkey instanceof Uint8Array) { |
|
mentionPubkey = Array.from(mentionPubkey).map(b => b.toString(16).padStart(2, '0')).join(''); |
|
} |
|
} |
|
} catch { |
|
// Keep original if decode fails |
|
} |
|
tags.push(['p', mentionPubkey]); |
|
} |
|
|
|
// Add client tag unless --no-client-tag is specified |
|
addClientTag(tags, args); |
|
|
|
const event = finalizeEvent({ |
|
kind: 1617, // PATCH |
|
created_at: Math.floor(Date.now() / 1000), |
|
tags, |
|
content: patchContent |
|
}, privateKeyBytes); |
|
|
|
await publishEventCommon(event, relays, privateKeyBytes, pubkey, json, 'Patch'); |
|
if (!json) { |
|
console.log(`Repository: ${ownerNpub}/${repoName}`); |
|
console.log(`Patch file: ${patchFile}`); |
|
} |
|
}
|
|
|