UNPKG

@aaronshaf/ger

Version:

Gerrit CLI and SDK - A modern CLI tool and TypeScript SDK for Gerrit Code Review, built with Effect-TS

90 lines (85 loc) 3.52 kB
import type { ChangeInfo, CommentInfo, MessageInfo } from '@/schemas/gerrit' import { sanitizeCDATA, escapeXML } from '@/utils/shell-safety' export const formatChangeAsXML = (change: ChangeInfo): string[] => { const lines: string[] = [] lines.push(` <change>`) lines.push(` <id>${escapeXML(change.change_id)}</id>`) lines.push(` <number>${change._number}</number>`) lines.push(` <subject><![CDATA[${sanitizeCDATA(change.subject)}]]></subject>`) lines.push(` <status>${escapeXML(change.status)}</status>`) lines.push(` <project>${escapeXML(change.project)}</project>`) lines.push(` <branch>${escapeXML(change.branch)}</branch>`) lines.push(` <owner>`) if (change.owner?.name) { lines.push(` <name><![CDATA[${sanitizeCDATA(change.owner.name)}]]></name>`) } if (change.owner?.email) { lines.push(` <email>${escapeXML(change.owner.email)}</email>`) } lines.push(` </owner>`) lines.push(` <created>${escapeXML(change.created || '')}</created>`) lines.push(` <updated>${escapeXML(change.updated || '')}</updated>`) lines.push(` </change>`) return lines } export const formatCommentsAsXML = (comments: readonly CommentInfo[]): string[] => { const lines: string[] = [] lines.push(` <comments>`) lines.push(` <count>${comments.length}</count>`) for (const comment of comments) { lines.push(` <comment>`) if (comment.id) lines.push(` <id>${escapeXML(comment.id)}</id>`) if (comment.path) { lines.push(` <path><![CDATA[${sanitizeCDATA(comment.path)}]]></path>`) } if (comment.line) lines.push(` <line>${comment.line}</line>`) if (comment.author?.name) { lines.push(` <author><![CDATA[${sanitizeCDATA(comment.author.name)}]]></author>`) } if (comment.updated) lines.push(` <updated>${escapeXML(comment.updated)}</updated>`) if (comment.message) { lines.push(` <message><![CDATA[${sanitizeCDATA(comment.message)}]]></message>`) } if (comment.unresolved) lines.push(` <unresolved>true</unresolved>`) lines.push(` </comment>`) } lines.push(` </comments>`) return lines } export const formatMessagesAsXML = (messages: readonly MessageInfo[]): string[] => { const lines: string[] = [] lines.push(` <messages>`) lines.push(` <count>${messages.length}</count>`) for (const message of messages) { lines.push(` <message>`) lines.push(` <id>${escapeXML(message.id)}</id>`) if (message.author?.name) { lines.push(` <author><![CDATA[${sanitizeCDATA(message.author.name)}]]></author>`) } if (message.author?._account_id) { lines.push(` <author_id>${message.author._account_id}</author_id>`) } lines.push(` <date>${escapeXML(message.date)}</date>`) if (message._revision_number) { lines.push(` <revision>${message._revision_number}</revision>`) } if (message.tag) { lines.push(` <tag>${escapeXML(message.tag)}</tag>`) } lines.push(` <message><![CDATA[${sanitizeCDATA(message.message)}]]></message>`) lines.push(` </message>`) } lines.push(` </messages>`) return lines } export const flattenComments = ( commentsMap: Record<string, readonly CommentInfo[]>, ): CommentInfo[] => { const comments: CommentInfo[] = [] for (const [path, fileComments] of Object.entries(commentsMap)) { for (const comment of fileComments) { comments.push({ ...comment, path }) } } return comments }