UNPKG

t-comm

Version:

专业、稳定、纯粹的工具库

590 lines (589 loc) 20.2 kB
/** MR 变更文件信息 */ export interface MRChange { /** 旧文件路径 */ old_path: string; /** 新文件路径 */ new_path: string; /** 是否新增文件 */ new_file: boolean; /** 是否重命名 */ renamed_file: boolean; /** 是否删除 */ deleted_file: boolean; /** diff 内容 */ diff: string; } /** MR 详情 */ export interface MRDetail { id: number; iid: number; title: string; description: string; state: string; source_branch: string; target_branch: string; author: { username: string; name: string; }; web_url: string; source_project_id: number; target_project_id: number; [k: string]: unknown; } /** MR 变更详情(含 diff),统一使用 changes 字段名 */ export interface MRChangesDetail extends MRDetail { changes: MRChange[]; } /** * 从 TGit MR 的 URL 中解析出项目名称和 MR ID * * iid 与 id 的区别: * - iid:项目内的序号,从 1 开始递增,即 URL 和 Web 界面上看到的数字(如 /merge_requests/112 中的 112) * - id:MR 在整个 TGit 系统中的全局唯一 ID,不同项目间不重复 * * 本函数从 URL 中解析出的数字是 iid(项目内序号),不是全局 id。 * 如需获取全局 id,可使用 queryMRByIId 通过 iid 查询 MR 详情后获取。 * * @param {string} url TGit MR 的 URL,如 https://git.woa.com/group/project/-/merge_requests/112 * @returns {{ projectName: string, mrIid: string } | null} 解析结果(mrIid 为 URL 中的 iid),解析失败返回 null * @example * * // URL 中的 112 是 iid(项目内序号) * parseMRUrl('https://git.woa.com/pmd-mobile/ai-tool/rd-ai-common/-/merge_requests/112/notes') * // => { projectName: 'pmd-mobile/ai-tool/rd-ai-common', mrIid: '112' } * * parseMRUrl('https://git.woa.com/coecology/xd/-/merge_requests/169') * // => { projectName: 'coecology/xd', mrIid: '169' } */ export declare function parseMRUrl(url: string): { projectName: string; mrIid: string; } | null; /** * 创建MR * @param {object} options 输入配置 * @param {string} options.projectName 项目名称 * @param {string} options.privateToken 密钥 * @param {string} options.sourceBranch 源分支 * @param {string} options.targetBranch 目标分支 * @param {number} [options.approverRule=1] 审批规则 * @param {number} [options.necessaryApproverRule=0] 必要审批规则 * @returns {Promise<object>} 请求Promise * @example * * createMR({ * projectName: 't-comm', * privateToken: 'xxxxx', * sourceBranch: 'master', * targetBranch: 'release', * }).then((resp) => { * * }) */ export declare function createMR({ projectName, privateToken, sourceBranch, targetBranch, approverRule, necessaryApproverRule, baseUrl, titlePrefix, title: customTitle, description, assigneeList, reviewerList, }: { projectName: string | number; privateToken: string; sourceBranch: string; targetBranch: string; approverRule?: number; necessaryApproverRule?: number; baseUrl?: string; /** MR 标题前缀,如 '[WIP]' 可防止被自动合入(仅在未显式传 title 时生效) */ titlePrefix?: string; /** 自定义 MR 标题;未传则自动生成 `${sourceBranch} => ${targetBranch}` */ title?: string; /** MR 描述 */ description?: string; /** * 评审人(Assignee)用户名列表(工蜂英文名/RTX)。 * 函数内部会调用 resolveUserIds 转换为数字 ID。 * 工蜂 v3 仅支持单个 assignee_id,传多人时取第一个能解析到的。 */ assigneeList?: string[]; /** * Reviewers 用户名列表(工蜂英文名/RTX)。 * 函数内部会调用 resolveUserIds 转换为数字 ID。 * 未传时会默认使用 assigneeList 作为 reviewers(与 GitApiService 行为保持一致)。 */ reviewerList?: string[]; }): Promise<any>; /** * 获取MR列表 * @param {object} options 输入配置 * @param {string} options.projectName 项目名称 * @param {string} options.privateToken 密钥 * @returns {Promise<object>} 请求Promise * @example * * getMrList({ * projectName: 't-comm', * privateToken: 'xxxxx', * }).then((resp) => { * * }) */ export declare function getMrList({ projectName, privateToken, baseUrl }: { projectName: string; privateToken: string; baseUrl?: string; }): Promise<object>; /** * 获取MR的一条评论 * @param {object} options 输入配置 * @param {string} options.projectName 项目名称 * @param {string} options.privateToken 密钥 * @param {string} options.mrId 某次MR的Id * @returns {Promise<object>} 请求Promise * @example * * getOneMrComments({ * projectName: 't-comm', * privateToken: 'xxxxx', * mrId: '1' * }).then((resp) => { * * }) */ export declare function getOneMrComments({ mrId, projectName, privateToken, baseUrl }: { projectName: string; mrId: string; privateToken: string; baseUrl?: string; }): Promise<object>; /** * 发表评审意见(同意/拒绝/评论/要求修改) * @param {object} options 输入配置 * @param {string} [options.projectName] 项目名称(与 url 二选一) * @param {string} options.privateToken 密钥 * @param {string} [options.reviewableId] 合并请求的 reviewable_id(与 url 二选一)。注意 reviewer/summary API 需要的既不是全局 id 也不是 iid,而是 reviewable_id,可通过 queryMRByIId 获取 * @param {string} [options.url] TGit MR 的 URL,传入后自动解析 projectName 和 mrIid,并自动调用 queryMRByIId 获取 reviewable_id * @param {string} options.reviewerEvent 评审人事件,可选:comment | approve | require_change | deny * @param {string} [options.summary] 评审信息摘要 * @returns {Promise<object>} 请求Promise * @example * * // 方式一:直接传入 projectName 和 reviewableId * reviewMR({ * projectName: 't-comm', * privateToken: 'xxxxx', * reviewableId: '1', * reviewerEvent: 'approve', * summary: 'LGTM', * }).then((resp) => { * * }) * * // 方式二:传入 URL 自动解析 * reviewMR({ * url: 'https://git.woa.com/coecology/xd/-/merge_requests/169', * privateToken: 'xxxxx', * reviewerEvent: 'approve', * }).then((resp) => { * * }) */ export declare function reviewMR({ baseUrl, reviewableId, projectName, privateToken, reviewerEvent, summary, url, }: { projectName?: string; reviewableId?: string; privateToken: string; reviewerEvent: 'comment' | 'approve' | 'require_change' | 'deny'; summary?: string; url?: string; baseUrl?: string; }): Promise<object>; /** * 根据 iid(项目内序号)查询 MR 评审信息 * * iid 与 id 的区别: * - iid:项目内的序号,从 1 开始递增,即 URL 和 Web 界面上看到的数字(如 /merge_requests/112 中的 112) * - id:MR 在整个 TGit 系统中的全局唯一 ID,不同项目间不重复 * * 对应 API:GET /api/v3/projects/:id/merge_request/iid/:merge_request_iid/review * * @param {object} options 输入配置 * @param {string} options.projectName 项目名称或项目全路径 * @param {string} options.privateToken 密钥 * @param {string} options.mrIid 合并请求在项目中的编号 iid(即 URL 中看到的数字) * @param {string} [options.baseUrl] 自定义 API 基础路径 * @returns {Promise<object>} MR 评审信息,包含 id(评审记录全局 ID)、reviewable_id(reviewer/summary 接口需要的 ID)、iid、title、description、author 等字段 * @example * * queryMRByIId({ * projectName: 'coecology/xd', * privateToken: 'xxxxx', * mrIid: '169', * }).then((resp) => { * console.log(resp.id); // 全局 id * console.log(resp.title); // MR 标题 * }) */ export declare function queryMRByIId({ projectName, privateToken, mrIid, baseUrl }: { projectName: string; mrIid: string; privateToken: string; baseUrl?: string; }): Promise<object>; /** * 通过 iid(项目内 MR 序号)获取 MR 的全局 id * * iid 与 id 的区别: * - iid:项目内的序号,从 1 开始递增,即 URL 和 Web 界面上看到的数字 * - id:MR 在整个 TGit 系统中的全局唯一 ID * * 工蜂 v3 API 的 merge_request 详情接口使用全局 id,而非 iid。 * 新建的 MR 在工蜂 API 侧可能有短暂同步延迟,本函数默认进行 3 次重试(3s 间隔)。 * * 对应工蜂 API:GET /api/v3/projects/:id/merge_requests?iid=:iid * * @param {object} options 输入配置 * @param {string | number} options.projectName 项目名称或项目 ID * @param {number | string} options.mrIid MR 的项目内序号 * @param {string} options.privateToken 密钥 * @param {string} [options.baseUrl] baseUrl * @param {number} [options.maxRetries=3] 最大重试次数 * @param {number} [options.retryDelay=3000] 重试间隔(毫秒) * @returns {Promise<number>} MR 的全局 id * @example * * getMRIdByIid({ * projectName: 'group/sub/repo', * mrIid: 112, * privateToken: 'xxxxx', * }).then((id) => { * console.log(id); // 全局 id * }) */ export declare function getMRIdByIid({ projectName, mrIid, privateToken, baseUrl, maxRetries, retryDelay, }: { projectName: string | number; mrIid: number | string; privateToken: string; baseUrl?: string; maxRetries?: number; retryDelay?: number; }): Promise<number>; /** * 获取 MR 详情(参数为 iid,内部自动转全局 id) * * 对应工蜂 API:GET /api/v3/projects/:id/merge_request/:id * * @param {object} options 输入配置 * @param {string | number} options.projectName 项目名称或项目 ID * @param {number | string} options.mrIid MR 的项目内序号 * @param {string} options.privateToken 密钥 * @param {string} [options.baseUrl] baseUrl * @returns {Promise<MRDetail>} MR 详情 * @example * * getMRDetail({ * projectName: 'coecology/xd', * mrIid: 169, * privateToken: 'xxxxx', * }).then((mr) => { * console.log(mr.title, mr.state); * }) */ export declare function getMRDetail({ projectName, mrIid, privateToken, baseUrl, }: { projectName: string | number; mrIid: number | string; privateToken: string; baseUrl?: string; }): Promise<MRDetail>; /** * 获取 MR 变更内容(含 diff) * * 对应工蜂 API:GET /api/v3/projects/:id/merge_request/:id/changes * * 工蜂 v3 API 返回的变更文件字段名为 `files`,本函数会额外映射一个 `changes` 字段 * 方便调用方以统一的字段名访问(同时保留 files)。 * * @param {object} options 输入配置 * @param {string | number} options.projectName 项目名称或项目 ID * @param {number | string} options.mrIid MR 的项目内序号 * @param {string} options.privateToken 密钥 * @param {string} [options.baseUrl] baseUrl * @returns {Promise<MRChangesDetail>} MR 变更详情 * @example * * getMRChanges({ * projectName: 'coecology/xd', * mrIid: 169, * privateToken: 'xxxxx', * }).then((res) => { * res.changes.forEach(c => console.log(c.new_path)); * }) */ export declare function getMRChanges({ projectName, mrIid, privateToken, baseUrl, }: { projectName: string | number; mrIid: number | string; privateToken: string; baseUrl?: string; }): Promise<MRChangesDetail>; /** * 在 MR 上提交评论(Note) * * - 不传 filePath/line:普通评论(贴在 MR 讨论区) * - 传 filePath 和 line:行内评论(贴在 diff 指定文件的指定行) * * 对应工蜂 API:POST /api/v3/projects/:id/merge_requests/:id/notes * * @param {object} options 输入配置 * @param {string | number} options.projectName 项目名称或项目 ID * @param {number | string} options.mrIid MR 的项目内序号 * @param {string} options.body 评论内容 * @param {string} options.privateToken 密钥 * @param {string} [options.filePath] 行内评论:diff 中的新文件路径 * @param {number} [options.line] 行内评论:新文件中的行号 * @param {'new' | 'old'} [options.lineType='new'] 行内评论:行类型,默认 new * @param {string} [options.baseUrl] baseUrl * @returns {Promise<{ id: number }>} 新建评论的 ID * @example * * // 1. 普通评论 * createMRNote({ * projectName: 'coecology/xd', * mrIid: 169, * body: 'LGTM', * privateToken: 'xxxxx', * }).then((res) => console.log(res.id)); * * // 2. 行内评论 * createMRNote({ * projectName: 'coecology/xd', * mrIid: 169, * body: '这里可以优化', * filePath: 'src/index.ts', * line: 12, * lineType: 'new', * privateToken: 'xxxxx', * }); */ export declare function createMRNote({ projectName, mrIid, body, privateToken, filePath, line, lineType, baseUrl, }: { projectName: string | number; mrIid: number | string; body: string; privateToken: string; filePath?: string; line?: number; lineType?: 'new' | 'old'; baseUrl?: string; }): Promise<{ id: number; }>; /** * 获取 MR 的所有评论(Notes)列表 * * 对应工蜂 API:GET /api/v3/projects/:id/merge_requests/:id/notes * * @param {object} options 输入配置 * @param {string | number} options.projectName 项目名称或项目 ID * @param {number | string} options.mrIid MR 的项目内序号 * @param {string} options.privateToken 密钥 * @param {number} [options.perPage=100] 每页数量 * @param {string} [options.baseUrl] baseUrl * @returns {Promise<Array<Record<string, unknown>>>} 评论列表 * @example * * getMRNotes({ * projectName: 'coecology/xd', * mrIid: 169, * privateToken: 'xxxxx', * }).then((notes) => { * notes.forEach(n => console.log(n.id, n.body)); * }) */ export declare function getMRNotes({ projectName, mrIid, privateToken, perPage, baseUrl, }: { projectName: string | number; mrIid: number | string; privateToken: string; perPage?: number; baseUrl?: string; }): Promise<Array<Record<string, unknown>>>; /** * 获取 MR 的单条评论(Note)详情 * * 对应工蜂 API:GET /api/v3/projects/:id/merge_requests/:id/notes/:noteId * * @param {object} options 输入配置 * @param {string | number} options.projectName 项目名称或项目 ID * @param {number | string} options.mrIid MR 的项目内序号 * @param {number | string} options.noteId 评论 ID * @param {string} options.privateToken 密钥 * @param {string} [options.baseUrl] baseUrl * @returns {Promise<Record<string, unknown>>} 评论详情 * @example * * getMRNoteById({ * projectName: 'coecology/xd', * mrIid: 169, * noteId: 123456, * privateToken: 'xxxxx', * }).then((note) => { * console.log(note.body); * }) */ export declare function getMRNoteById({ projectName, mrIid, noteId, privateToken, baseUrl, }: { projectName: string | number; mrIid: number | string; noteId: number | string; privateToken: string; baseUrl?: string; }): Promise<Record<string, unknown>>; /** * 更新 MR 上的已有评论 * * 对应工蜂 API:PUT /api/v3/projects/:id/merge_requests/:id/notes/:noteId * * @param {object} options 输入配置 * @param {string | number} options.projectName 项目名称或项目 ID * @param {number | string} options.mrIid MR 的项目内序号 * @param {number | string} options.noteId 要更新的评论 ID * @param {string} options.body 新的评论内容 * @param {string} options.privateToken 密钥 * @param {string} [options.baseUrl] baseUrl * @returns {Promise<{ id: number }>} 更新后的评论 * @example * * updateMRNote({ * projectName: 'coecology/xd', * mrIid: 169, * noteId: 123456, * body: '更新后的评论内容', * privateToken: 'xxxxx', * }).then((res) => console.log(res.id)); */ export declare function updateMRNote({ projectName, mrIid, noteId, body, privateToken, baseUrl, }: { projectName: string | number; mrIid: number | string; noteId: number | string; body: string; privateToken: string; baseUrl?: string; }): Promise<{ id: number; }>; /** * 回复 MR 上的已有评论(在讨论串中回复) * * 对应工蜂 API:POST /api/v3/projects/:id/merge_requests/:id/notes/:noteId/replies * * @param {object} options 输入配置 * @param {string | number} options.projectName 项目名称或项目 ID * @param {number | string} options.mrIid MR 的项目内序号 * @param {number | string} options.parentNoteId 要回复的父评论 ID * @param {string} options.body 回复内容 * @param {string} options.privateToken 密钥 * @param {string} [options.baseUrl] baseUrl * @returns {Promise<{ id: number }>} 新建回复的 ID * @example * * createNoteReply({ * projectName: 'coecology/xd', * mrIid: 169, * parentNoteId: 123456, * body: '同意上面的意见', * privateToken: 'xxxxx', * }).then((res) => console.log(res.id)); */ export declare function createNoteReply({ projectName, mrIid, parentNoteId, body, privateToken, baseUrl, }: { projectName: string | number; mrIid: number | string; parentNoteId: number | string; body: string; privateToken: string; baseUrl?: string; }): Promise<{ id: number; }>; /** * 回复代码评审中的评论(行内评论 reply) * * 对应工蜂 API:POST /api/v3/projects/:id/reviews/:reviewId/notes/:noteId/replies * * 只能回复代码行上的第一条评论,不支持回复「已是回复」的评论。 * * @param {object} options 输入配置 * @param {string | number} options.projectName 项目名称或项目 ID * @param {number | string} options.reviewId 评审记录 ID * @param {number | string} options.noteId 要回复的评论 ID * @param {string} options.body 回复内容 * @param {string} options.privateToken 密钥 * @param {string} [options.baseUrl] baseUrl * @returns {Promise<{ id: number }>} 新建回复的 ID * @example * * createReviewNoteReply({ * projectName: 'coecology/xd', * reviewId: 9999, * noteId: 123456, * body: '这里应该补一下边界检查', * privateToken: 'xxxxx', * }).then((res) => console.log(res.id)); */ export declare function createReviewNoteReply({ projectName, reviewId, noteId, body, privateToken, baseUrl, }: { projectName: string | number; reviewId: number | string; noteId: number | string; body: string; privateToken: string; baseUrl?: string; }): Promise<{ id: number; }>; /** * 关闭 MR(参数为 iid,内部自动转全局 id) * * 对应工蜂 API:PUT /api/v3/projects/:id/merge_request/:id body: { state_event: 'close' } * * @param {object} options 输入配置 * @param {string | number} options.projectName 项目名称或项目 ID * @param {number | string} options.mrIid MR 的项目内序号 * @param {string} options.privateToken 密钥 * @param {string} [options.baseUrl] baseUrl * @returns {Promise<MRDetail>} 关闭后的 MR 详情 * @example * * closeMR({ * projectName: 'coecology/xd', * mrIid: 169, * privateToken: 'xxxxx', * }).then((mr) => { * console.log(mr.state); * }) */ export declare function closeMR({ projectName, mrIid, privateToken, baseUrl, }: { projectName: string | number; mrIid: number | string; privateToken: string; baseUrl?: string; }): Promise<MRDetail>; /** * 通过 MR URL 关闭一个 MR * * 内部流程: * 1. 调用 {@link parseMRUrl} 从 URL 中解析出 projectName + mrIid * 2. 调用 {@link closeMR} 完成关闭操作 * * @param {object} options 输入配置 * @param {string} options.mrUrl MR 的 URL * @param {string} options.privateToken 密钥 * @param {string} [options.baseUrl] baseUrl * @returns {Promise<{ projectName: string; mrIid: string; raw: MRDetail }>} 解析与关闭结果 * @example * * closeMRByUrl({ * mrUrl: 'https://git.woa.com/coecology/xd/-/merge_requests/169', * privateToken: 'xxxxx', * }).then((res) => { * console.log(res.projectName, res.mrIid, res.raw.state); * }) */ export declare function closeMRByUrl({ mrUrl, privateToken, baseUrl, }: { mrUrl: string; privateToken: string; baseUrl?: string; }): Promise<{ projectName: string; mrIid: string; raw: MRDetail; }>;