mirror of
https://github.com/purrgrammer/grimoire.git
synced 2026-04-12 00:17:02 +02:00
373 lines
11 KiB
TypeScript
373 lines
11 KiB
TypeScript
import type { NostrEvent } from "@/types/nostr";
|
|
import { getTagValue } from "applesauce-core/helpers";
|
|
|
|
/**
|
|
* NIP-34 Helper Functions
|
|
* Utility functions for parsing NIP-34 git event tags
|
|
*/
|
|
|
|
// ============================================================================
|
|
// Repository Event Helpers (Kind 30617)
|
|
// ============================================================================
|
|
|
|
/**
|
|
* Get the repository name from a repository event
|
|
* @param event Repository event (kind 30617)
|
|
* @returns Repository name or undefined
|
|
*/
|
|
export function getRepositoryName(event: NostrEvent): string | undefined {
|
|
return getTagValue(event, "name");
|
|
}
|
|
|
|
/**
|
|
* Get the repository description
|
|
* @param event Repository event (kind 30617)
|
|
* @returns Repository description or undefined
|
|
*/
|
|
export function getRepositoryDescription(
|
|
event: NostrEvent,
|
|
): string | undefined {
|
|
return getTagValue(event, "description");
|
|
}
|
|
|
|
/**
|
|
* Get the repository identifier (d tag)
|
|
* @param event Repository event (kind 30617)
|
|
* @returns Repository identifier or undefined
|
|
*/
|
|
export function getRepositoryIdentifier(event: NostrEvent): string | undefined {
|
|
return getTagValue(event, "d");
|
|
}
|
|
|
|
/**
|
|
* Get all clone URLs from a repository event
|
|
* @param event Repository event (kind 30617)
|
|
* @returns Array of clone URLs
|
|
*/
|
|
export function getCloneUrls(event: NostrEvent): string[] {
|
|
return event.tags.filter((t) => t[0] === "clone").map((t) => t[1]);
|
|
}
|
|
|
|
/**
|
|
* Get all web URLs from a repository event
|
|
* @param event Repository event (kind 30617)
|
|
* @returns Array of web URLs
|
|
*/
|
|
export function getWebUrls(event: NostrEvent): string[] {
|
|
return event.tags.filter((t) => t[0] === "web").map((t) => t[1]);
|
|
}
|
|
|
|
/**
|
|
* Get all maintainer pubkeys from a repository event
|
|
* @param event Repository event (kind 30617)
|
|
* @returns Array of maintainer pubkeys
|
|
*/
|
|
export function getMaintainers(event: NostrEvent): string[] {
|
|
return event.tags
|
|
.filter((t) => t[0] === "maintainers")
|
|
.map((t) => t[1])
|
|
.filter((p: string) => p !== event.pubkey);
|
|
}
|
|
|
|
/**
|
|
* Get relay hints for patches and issues
|
|
* @param event Repository event (kind 30617)
|
|
* @returns Array of relay URLs
|
|
*/
|
|
export function getRepositoryRelays(event: NostrEvent): string[] {
|
|
const relaysTag = event.tags.find((t) => t[0] === "relays");
|
|
if (!relaysTag) return [];
|
|
const [, ...relays] = relaysTag;
|
|
return relays;
|
|
}
|
|
|
|
// ============================================================================
|
|
// Issue Event Helpers (Kind 1621)
|
|
// ============================================================================
|
|
|
|
/**
|
|
* Get the issue title/subject
|
|
* @param event Issue event (kind 1621)
|
|
* @returns Issue title or undefined
|
|
*/
|
|
export function getIssueTitle(event: NostrEvent): string | undefined {
|
|
return getTagValue(event, "subject");
|
|
}
|
|
|
|
/**
|
|
* Get all issue labels/tags
|
|
* @param event Issue event (kind 1621)
|
|
* @returns Array of label strings
|
|
*/
|
|
export function getIssueLabels(event: NostrEvent): string[] {
|
|
return event.tags.filter((t) => t[0] === "t").map((t) => t[1]);
|
|
}
|
|
|
|
/**
|
|
* Get the repository address pointer for an issue
|
|
* @param event Issue event (kind 1621)
|
|
* @returns Repository address pointer (a tag) or undefined
|
|
*/
|
|
export function getIssueRepositoryAddress(
|
|
event: NostrEvent,
|
|
): string | undefined {
|
|
return getTagValue(event, "a");
|
|
}
|
|
|
|
/**
|
|
* Get the repository owner pubkey for an issue
|
|
* @param event Issue event (kind 1621)
|
|
* @returns Repository owner pubkey or undefined
|
|
*/
|
|
export function getIssueRepositoryOwner(event: NostrEvent): string | undefined {
|
|
return getTagValue(event, "p");
|
|
}
|
|
|
|
// ============================================================================
|
|
// Patch Event Helpers (Kind 1617)
|
|
// ============================================================================
|
|
|
|
/**
|
|
* Get the patch subject from content or subject tag
|
|
* @param event Patch event (kind 1617)
|
|
* @returns Patch subject/title or undefined
|
|
*/
|
|
export function getPatchSubject(event: NostrEvent): string | undefined {
|
|
// Try subject tag first
|
|
const subjectTag = getTagValue(event, "subject");
|
|
if (subjectTag) return subjectTag;
|
|
|
|
// Try to extract from content (first line or "Subject:" header from git format-patch)
|
|
const content = event.content.trim();
|
|
const subjectMatch = content.match(/^Subject:\s*(.+?)$/m);
|
|
if (subjectMatch) return subjectMatch[1].trim();
|
|
|
|
// Fallback to first line
|
|
const firstLine = content.split("\n")[0];
|
|
return firstLine?.length > 0 ? firstLine : undefined;
|
|
}
|
|
|
|
/**
|
|
* Get the commit ID from a patch event
|
|
* @param event Patch event (kind 1617)
|
|
* @returns Commit ID or undefined
|
|
*/
|
|
export function getPatchCommitId(event: NostrEvent): string | undefined {
|
|
return getTagValue(event, "commit");
|
|
}
|
|
|
|
/**
|
|
* Get the parent commit ID from a patch event
|
|
* @param event Patch event (kind 1617)
|
|
* @returns Parent commit ID or undefined
|
|
*/
|
|
export function getPatchParentCommit(event: NostrEvent): string | undefined {
|
|
return getTagValue(event, "parent-commit");
|
|
}
|
|
|
|
/**
|
|
* Get committer info from a patch event
|
|
* @param event Patch event (kind 1617)
|
|
* @returns Committer object with name, email, timestamp, timezone or undefined
|
|
*/
|
|
export function getPatchCommitter(
|
|
event: NostrEvent,
|
|
):
|
|
| { name: string; email: string; timestamp: string; timezone: string }
|
|
| undefined {
|
|
const committerTag = event.tags.find((t) => t[0] === "committer");
|
|
if (!committerTag || committerTag.length < 5) return undefined;
|
|
|
|
const [, name, email, timestamp, timezone] = committerTag;
|
|
return { name, email, timestamp, timezone };
|
|
}
|
|
|
|
/**
|
|
* Get the repository address for a patch
|
|
* @param event Patch event (kind 1617)
|
|
* @returns Repository address pointer (a tag) or undefined
|
|
*/
|
|
export function getPatchRepositoryAddress(
|
|
event: NostrEvent,
|
|
): string | undefined {
|
|
return getTagValue(event, "a");
|
|
}
|
|
|
|
/**
|
|
* Check if patch is root/first in series
|
|
* @param event Patch event (kind 1617)
|
|
* @returns True if this is a root patch
|
|
*/
|
|
export function isPatchRoot(event: NostrEvent): boolean {
|
|
return event.tags.some((t) => t[0] === "t" && t[1] === "root");
|
|
}
|
|
|
|
/**
|
|
* Check if patch is first in a revision series
|
|
* @param event Patch event (kind 1617)
|
|
* @returns True if this is a root revision
|
|
*/
|
|
export function isPatchRootRevision(event: NostrEvent): boolean {
|
|
return event.tags.some((t) => t[0] === "t" && t[1] === "root-revision");
|
|
}
|
|
|
|
// ============================================================================
|
|
// Pull Request Event Helpers (Kind 1618)
|
|
// ============================================================================
|
|
|
|
/**
|
|
* Get the PR subject/title
|
|
* @param event PR event (kind 1618)
|
|
* @returns PR subject or undefined
|
|
*/
|
|
export function getPullRequestSubject(event: NostrEvent): string | undefined {
|
|
return getTagValue(event, "subject");
|
|
}
|
|
|
|
/**
|
|
* Get PR labels
|
|
* @param event PR event (kind 1618)
|
|
* @returns Array of label strings
|
|
*/
|
|
export function getPullRequestLabels(event: NostrEvent): string[] {
|
|
return event.tags.filter((t) => t[0] === "t").map((t) => t[1]);
|
|
}
|
|
|
|
/**
|
|
* Get the current commit ID (tip of PR branch)
|
|
* @param event PR event (kind 1618)
|
|
* @returns Commit ID or undefined
|
|
*/
|
|
export function getPullRequestCommitId(event: NostrEvent): string | undefined {
|
|
return getTagValue(event, "c");
|
|
}
|
|
|
|
/**
|
|
* Get all clone URLs for a PR
|
|
* @param event PR event (kind 1618)
|
|
* @returns Array of clone URLs
|
|
*/
|
|
export function getPullRequestCloneUrls(event: NostrEvent): string[] {
|
|
return event.tags.filter((t) => t[0] === "clone").map((t) => t[1]);
|
|
}
|
|
|
|
/**
|
|
* Get the branch name for a PR
|
|
* @param event PR event (kind 1618)
|
|
* @returns Branch name or undefined
|
|
*/
|
|
export function getPullRequestBranchName(
|
|
event: NostrEvent,
|
|
): string | undefined {
|
|
return getTagValue(event, "branch-name");
|
|
}
|
|
|
|
/**
|
|
* Get the merge base commit ID
|
|
* @param event PR event (kind 1618)
|
|
* @returns Merge base commit ID or undefined
|
|
*/
|
|
export function getPullRequestMergeBase(event: NostrEvent): string | undefined {
|
|
return getTagValue(event, "merge-base");
|
|
}
|
|
|
|
/**
|
|
* Get the repository address for a PR
|
|
* @param event PR event (kind 1618)
|
|
* @returns Repository address pointer (a tag) or undefined
|
|
*/
|
|
export function getPullRequestRepositoryAddress(
|
|
event: NostrEvent,
|
|
): string | undefined {
|
|
return getTagValue(event, "a");
|
|
}
|
|
|
|
// ============================================================================
|
|
// Repository State Event Helpers (Kind 30618)
|
|
// ============================================================================
|
|
|
|
/**
|
|
* Get the HEAD reference from a repository state event
|
|
* @param event Repository state event (kind 30618)
|
|
* @returns HEAD reference (e.g., "ref: refs/heads/main") or undefined
|
|
*/
|
|
export function getRepositoryStateHead(event: NostrEvent): string | undefined {
|
|
return getTagValue(event, "HEAD");
|
|
}
|
|
|
|
/**
|
|
* Parse HEAD reference to extract branch name
|
|
* @param headRef HEAD reference string (e.g., "ref: refs/heads/main")
|
|
* @returns Branch name (e.g., "main") or undefined
|
|
*/
|
|
export function parseHeadBranch(
|
|
headRef: string | undefined,
|
|
): string | undefined {
|
|
if (!headRef) return undefined;
|
|
const match = headRef.match(/^ref:\s*refs\/heads\/(.+)$/);
|
|
return match ? match[1] : undefined;
|
|
}
|
|
|
|
/**
|
|
* Get all git refs from a repository state event
|
|
* @param event Repository state event (kind 30618)
|
|
* @returns Array of { ref: string, hash: string } objects
|
|
*/
|
|
export function getRepositoryStateRefs(
|
|
event: NostrEvent,
|
|
): Array<{ ref: string; hash: string }> {
|
|
return event.tags
|
|
.filter((t) => t[0].startsWith("refs/"))
|
|
.map((t) => ({ ref: t[0], hash: t[1] }));
|
|
}
|
|
|
|
/**
|
|
* Get the commit hash that HEAD points to
|
|
* @param event Repository state event (kind 30618)
|
|
* @returns Commit hash or undefined
|
|
*/
|
|
export function getRepositoryStateHeadCommit(
|
|
event: NostrEvent,
|
|
): string | undefined {
|
|
const headRef = getRepositoryStateHead(event);
|
|
const branch = parseHeadBranch(headRef);
|
|
if (!branch) return undefined;
|
|
|
|
// Find the refs/heads/{branch} tag
|
|
const branchRef = `refs/heads/${branch}`;
|
|
const branchTag = event.tags.find((t) => t[0] === branchRef);
|
|
return branchTag ? branchTag[1] : undefined;
|
|
}
|
|
|
|
/**
|
|
* Get branches from repository state refs
|
|
* @param event Repository state event (kind 30618)
|
|
* @returns Array of { name: string, hash: string } objects
|
|
*/
|
|
export function getRepositoryStateBranches(
|
|
event: NostrEvent,
|
|
): Array<{ name: string; hash: string }> {
|
|
return event.tags
|
|
.filter((t) => t[0].startsWith("refs/heads/"))
|
|
.map((t) => ({
|
|
name: t[0].replace("refs/heads/", ""),
|
|
hash: t[1],
|
|
}));
|
|
}
|
|
|
|
/**
|
|
* Get tags from repository state refs
|
|
* @param event Repository state event (kind 30618)
|
|
* @returns Array of { name: string, hash: string } objects
|
|
*/
|
|
export function getRepositoryStateTags(
|
|
event: NostrEvent,
|
|
): Array<{ name: string; hash: string }> {
|
|
return event.tags
|
|
.filter((t) => t[0].startsWith("refs/tags/"))
|
|
.map((t) => ({
|
|
name: t[0].replace("refs/tags/", ""),
|
|
hash: t[1],
|
|
}));
|
|
}
|