test add git modules

This commit is contained in:
xiongxiao
2026-02-02 04:46:21 +08:00
parent 412c057756
commit 69f2f4dc6a
2 changed files with 708 additions and 0 deletions

676
src/git/index.ts Normal file
View File

@@ -0,0 +1,676 @@
import { CNBCore, CNBCoreOptions, Result } from "../cnb-core.ts";
/**
* Git 提交信息
*/
export type Commit = {
sha: string;
short_sha: string;
title: string;
message: string;
author: {
name: string;
email: string;
username: string;
avatar_url: string;
};
committer: {
name: string;
email: string;
username: string;
avatar_url: string;
};
parents: Array<{ sha: string }>;
created_at: string;
};
/**
* Git 分支信息
*/
export type Branch = {
name: string;
commit: {
sha: string;
url: string;
};
};
/**
* Git 分支详细信息
*/
export type BranchDetail = Branch & {
protected: boolean;
default: boolean;
};
/**
* Git 标签信息
*/
export type Tag = {
name: string;
commit: {
sha: string;
url: string;
};
message: string;
annotation: Record<string, any>;
created_at: string;
};
/**
* Git 文件内容信息
*/
export type Content = {
name: string;
path: string;
sha: string;
size: number;
url: string;
html_url: string;
git_url: string;
download_url: string;
type: string;
content?: string;
encoding?: string;
};
/**
* Git Blob 对象
*/
export type Blob = {
sha: string;
size: number;
url: string;
content?: string;
};
/**
* Git 比较结果
*/
export type CompareResponse = {
status: string;
ahead_by: number;
behind_by: number;
total_commits: number;
commits: Commit[];
files: Array<{
sha: string;
filename: string;
status: string;
additions: number;
deletions: number;
changes: number;
patch?: string;
}>;
};
/**
* Git 提交状态
*/
export type CommitStatus = {
id: string;
state: string;
description: string;
target_url: string;
context: string;
created_at: string;
updated_at: string;
};
/**
* Git 提交附件
*/
export type CommitAsset = {
id: string;
name: string;
path: string;
sha1: string;
size: number;
created_at: string;
uploader: {
username: string;
nickname: string;
avatar_url: string;
};
};
/**
* Git 提交附件上传 URL
*/
export type CommitAssetUploadURL = {
upload_url: string;
verify_url: string;
upload_token: string;
};
/**
* Git 标签注释
*/
export type TagAnnotation = {
key: string;
value: string;
creator: string;
created_at: string;
};
/**
* Git 头引用
*/
export type HeadRef = {
default_branch: string;
};
/**
* Git 操作类
* 提供 Git 相关的 API 操作,包括提交、分支、标签、文件等
*/
export class Git extends CNBCore {
constructor(options: CNBCoreOptions) {
super({ token: options.token, cookie: options.cookie });
}
/**
* 查询提交列表
* @param repo 仓库名称,格式:组织名称/仓库名称
* @param params 查询参数
* @returns 提交列表
*/
async listCommits(repo: string, params?: ListCommitsParams): Promise<Result<Commit[]>> {
const url = `/${repo}/-/git/commits`;
return this.get({ url, params });
}
/**
* 查询指定提交
* @param repo 仓库名称,格式:组织名称/仓库名称
* @param ref 提交的哈希值或分支名称
* @returns 提交信息
*/
async getCommit(repo: string, ref: string): Promise<Result<Commit>> {
const url = `/${repo}/-/git/commits/${ref}`;
return this.get({ url });
}
/**
* 查询指定提交的提交状态
* @param repo 仓库名称,格式:组织名称/仓库名称
* @param commitish Git 引用标识符,分支名称、提交哈希值或标签名称
* @returns 提交状态列表
*/
async getCommitStatuses(repo: string, commitish: string): Promise<Result<CommitStatus[]>> {
const url = `/${repo}/-/git/commit-statuses/${commitish}`;
return this.get({ url });
}
/**
* 查询分支列表
* @param repo 仓库名称,格式:组织名称/仓库名称
* @param params 分页参数
* @returns 分支列表
*/
async listBranches(repo: string, params?: PaginationParams): Promise<Result<Branch[]>> {
const url = `/${repo}/-/git/branches`;
return this.get({ url, params });
}
/**
* 创建新分支
* @param repo 仓库名称,格式:组织名称/仓库名称
* @param data 创建分支的数据
* @returns 创建结果
*/
async createBranch(repo: string, data: CreateBranchData): Promise<Result<void>> {
const url = `/${repo}/-/git/branches`;
return this.post({ url, data });
}
/**
* 查询指定分支
* @param repo 仓库名称,格式:组织名称/仓库名称
* @param branch 分支名称
* @returns 分支详细信息
*/
async getBranch(repo: string, branch: string): Promise<Result<BranchDetail>> {
const url = `/${repo}/-/git/branches/${branch}`;
return this.get({ url });
}
/**
* 删除指定分支
* @param repo 仓库名称,格式:组织名称/仓库名称
* @param branch 分支名称
* @returns 删除结果
*/
async deleteBranch(repo: string, branch: string): Promise<Result<void>> {
const url = `/${repo}/-/git/branches/${branch}`;
return this.delete({ url });
}
/**
* 查询标签列表
* @param repo 仓库名称,格式:组织名称/仓库名称
* @param params 分页参数
* @returns 标签列表
*/
async listTags(repo: string, params?: PaginationParams): Promise<Result<Tag[]>> {
const url = `/${repo}/-/git/tags`;
return this.get({ url, params });
}
/**
* 创建标签
* @param repo 仓库名称,格式:组织名称/仓库名称
* @param data 创建标签的数据
* @returns 创建的标签信息
*/
async createTag(repo: string, data: CreateTagData): Promise<Result<Tag>> {
const url = `/${repo}/-/git/tags`;
return this.post({ url, data });
}
/**
* 查询指定标签
* @param repo 仓库名称,格式:组织名称/仓库名称
* @param tag 标签名称
* @returns 标签信息
*/
async getTag(repo: string, tag: string): Promise<Result<Tag>> {
const url = `/${repo}/-/git/tags/${tag}`;
return this.get({ url });
}
/**
* 删除指定标签
* @param repo 仓库名称,格式:组织名称/仓库名称
* @param tag 标签名称
* @returns 删除结果
*/
async deleteTag(repo: string, tag: string): Promise<Result<void>> {
const url = `/${repo}/-/git/tags/${tag}`;
return this.delete({ url });
}
/**
* 创建 Blob 对象
* @param repo 仓库名称,格式:组织名称/仓库名称
* @param data 创建 Blob 的数据
* @returns 创建的 Blob 信息
*/
async createBlob(repo: string, data: CreateBlobData): Promise<Result<Blob>> {
const url = `/${repo}/-/git/blobs`;
return this.post({ url, data });
}
/**
* 查询仓库文件内容(根目录)
* @param repo 仓库名称,格式:组织名称/仓库名称
* @param params 查询参数
* @returns 文件或目录内容
*/
async getContent(repo: string, params?: GetContentParams): Promise<Result<Content>> {
const url = `/${repo}/-/git/contents`;
return this.get({ url, params });
}
/**
* 查询指定路径的文件内容
* @param repo 仓库名称,格式:组织名称/仓库名称
* @param filePath 文件路径
* @param params 查询参数
* @returns 文件内容
*/
async getContentWithPath(repo: string, filePath: string, params?: GetContentWithPathParams): Promise<Result<Content>> {
const url = `/${repo}/-/git/contents/${filePath}`;
return this.get({ url, params });
}
/**
* 获取原始文件内容
* @param repo 仓库名称,格式:组织名称/仓库名称
* @param refWithPath Git 引用(分支、标签、提交哈希)和文件路径
* @param params 查询参数
* @returns 原始文件内容
*/
async getRaw(repo: string, refWithPath: string, params?: GetRawParams): Promise<string> {
const url = `/${repo}/-/git/raw/${refWithPath}`;
const response = await this.get({ url, params, useOrigin: true });
return response;
}
/**
* 下载仓库内容归档
* @param repo 仓库名称,格式:组织名称/仓库名称
* @param refWithPath Git 引用(分支名、标签名、提交哈希或分支名/文件路径)
* @param useOrigin 是否返回原始响应
* @returns 归档文件
*/
async getArchive(repo: string, refWithPath: string, useOrigin?: boolean): Promise<any> {
const url = `/${repo}/-/git/archive/${refWithPath}`;
return this.get({ url, useOrigin });
}
/**
* 打包下载提交变更文件
* @param repo 仓库名称,格式:组织名称/仓库名称
* @param sha1 提交的哈希值
* @returns 变更文件归档
*/
async getArchiveCommitChangedFiles(repo: string, sha1: string): Promise<any> {
const url = `/${repo}/-/git/archive-commit-changed-files/${sha1}`;
return this.get({ url, useOrigin: true });
}
/**
* 打包下载两次引用之间的变更文件
* @param repo 仓库名称,格式:组织名称/仓库名称
* @param baseHead 用于 Git 比较操作的基准和头部分支或提交的 SHA 值格式base...head
* @returns 变更文件归档
*/
async getArchiveCompareChangedFiles(repo: string, baseHead: string): Promise<any> {
const url = `/${repo}/-/git/archive-compare-changed-files/${baseHead}`;
return this.get({ url, useOrigin: true });
}
/**
* 查询指定提交的元数据
* @param repo 仓库名称,格式:组织名称/仓库名称
* @param sha 提交的哈希值
* @returns 提交元数据列表
*/
async getCommitAnnotations(repo: string, sha: string): Promise<Result<TagAnnotation[]>> {
const url = `/${repo}/-/git/commit-annotations/${sha}`;
return this.get({ url });
}
/**
* 设定指定提交的元数据
* @param repo 仓库名称,格式:组织名称/仓库名称
* @param sha 提交的哈希值
* @param data 提交的元数据
* @returns 设置结果
*/
async putCommitAnnotations(repo: string, sha: string, data: PutCommitAnnotationsData): Promise<Result<void>> {
const url = `/${repo}/-/git/commit-annotations/${sha}`;
return this.put({ url, data });
}
/**
* 删除指定提交的元数据
* @param repo 仓库名称,格式:组织名称/仓库名称
* @param sha 提交的哈希值
* @param key 提交的元数据键名
* @returns 删除结果
*/
async deleteCommitAnnotation(repo: string, sha: string, key: string): Promise<Result<void>> {
const url = `/${repo}/-/git/commit-annotations/${sha}/${key}`;
return this.delete({ url });
}
/**
* 批量查询提交的元数据
* @param repo 仓库名称,格式:组织名称/仓库名称
* @param data 包含多个提交哈希的请求数据
* @returns 提交元数据列表
*/
async getCommitAnnotationsInBatch(repo: string, data: GetCommitAnnotationsInBatchData): Promise<Result<TagAnnotation[]>> {
const url = `/${repo}/-/git/commit-annotations-in-batch`;
return this.post({ url, data });
}
/**
* 查询指定提交的附件列表
* @param repo 仓库名称,格式:组织名称/仓库名称
* @param sha1 提交的哈希值
* @returns 附件列表
*/
async getCommitAssetsBySha(repo: string, sha1: string): Promise<Result<CommitAsset[]>> {
const url = `/${repo}/-/git/commit-assets/${sha1}`;
return this.get({ url });
}
/**
* 新增提交附件(获取上传 URL
* @param repo 仓库名称,格式:组织名称/仓库名称
* @param sha1 提交的哈希值
* @param data 创建附件上传 URL 的数据
* @returns 上传 URL 信息
*/
async postCommitAssetUploadURL(repo: string, sha1: string, data: PostCommitAssetUploadURLData): Promise<Result<CommitAssetUploadURL>> {
const url = `/${repo}/-/git/commit-assets/${sha1}/asset-upload-url`;
return this.post({ url, data });
}
/**
* 确认提交附件上传完成
* @param repo 仓库名称,格式:组织名称/仓库名称
* @param sha1 提交的哈希值
* @param uploadToken 上传令牌
* @param assetPath 附件路径
* @param params 确认参数
* @returns 确认结果
*/
async postCommitAssetUploadConfirmation(repo: string, sha1: string, uploadToken: string, assetPath: string, params?: PostCommitAssetUploadConfirmationParams): Promise<Result<void>> {
const url = `/${repo}/-/git/commit-assets/${sha1}/asset-upload-confirmation/${uploadToken}/${assetPath}`;
return this.post({ url, params });
}
/**
* 删除指定提交的附件
* @param repo 仓库名称,格式:组织名称/仓库名称
* @param sha1 提交的哈希值
* @param assetId 附件唯一标识符
* @returns 删除结果
*/
async deleteCommitAsset(repo: string, sha1: string, assetId: string): Promise<Result<void>> {
const url = `/${repo}/-/git/commit-assets/${sha1}/${assetId}`;
return this.delete({ url });
}
/**
* 获取提交附件下载链接
* @param repo 仓库名称,格式:组织名称/仓库名称
* @param commitId 提交的哈希值
* @param filename 文件名称
* @param params 查询参数
* @returns 302 重定向到下载地址
*/
async getCommitAssets(repo: string, commitId: string, filename: string, params?: GetCommitAssetsParams): Promise<any> {
const url = `/${repo}/-/commit-assets/download/${commitId}/${filename}`;
return this.get({ url, params, useOrigin: true });
}
/**
* 比较两个提交、分支或标签之间的差异
* @param repo 仓库名称,格式:组织名称/仓库名称
* @param baseHead 用于 Git 比较操作的基准和头部分支或提交的 SHA 值格式base...head
* @returns 比较结果
*/
async getCompareCommits(repo: string, baseHead: string): Promise<Result<CompareResponse>> {
const url = `/${repo}/-/git/compare/${baseHead}`;
return this.get({ url });
}
/**
* 获取仓库默认分支
* @param repo 仓库名称,格式:组织名称/仓库名称
* @returns 默认分支信息
*/
async getHead(repo: string): Promise<Result<HeadRef>> {
const url = `/${repo}/-/git/head`;
return this.get({ url });
}
/**
* 查询指定标签的元数据
* @param repo 仓库名称,格式:组织名称/仓库名称
* @param tag 标签名称
* @returns 标签元数据列表
*/
async getTagAnnotations(repo: string, tag: string): Promise<Result<TagAnnotation[]>> {
const url = `/${repo}/-/git/tag-annotations/${tag}`;
return this.get({ url });
}
/**
* 设定指定标签的元数据
* @param repo 仓库名称,格式:组织名称/仓库名称
* @param tag 标签名称
* @param data 标签元数据
* @returns 设置结果
*/
async putTagAnnotations(repo: string, tag: string, data: PutTagAnnotationsData): Promise<Result<void>> {
const url = `/${repo}/-/git/tag-annotations/${tag}`;
return this.put({ url, data });
}
/**
* 删除指定标签的元数据
* @param repo 仓库名称,格式:组织名称/仓库名称
* @param tagWithKey 标签名称和键名组合
* @returns 删除结果
*/
async deleteTagAnnotation(repo: string, tagWithKey: string): Promise<Result<void>> {
const url = `/${repo}/-/git/tag-annotations/${tagWithKey}`;
return this.delete({ url });
}
}
/**
* 分页参数
*/
type PaginationParams = {
/** 分页页码,默认: 1 */
page?: number;
/** 分页页大小,默认: 30 */
page_size?: number;
};
/**
* 查询提交列表参数
*/
type ListCommitsParams = PaginationParams & {
/** 提交标识符,分支名称或提交哈希值 */
sha?: string;
/** 作者匹配模式,支持 Git 原生正则表达式 */
author?: string;
/** 提交者匹配模式,支持 Git 原生正则表达式 */
committer?: string;
/** 提交时间起始范围示例2025-01-01T00:00:00Z */
since?: string;
/** 提交时间结束范围示例2025-12-31T23:59:59Z */
until?: string;
};
/**
* 创建分支参数
*/
type CreateBranchData = {
/** 分支名称 */
branch_name: string;
/** 起始点,默认使用仓库默认分支 */
start_point?: string;
};
/**
* 创建标签参数
*/
type CreateTagData = {
/** 标签名称 */
tag_name: string;
/** 目标提交或分支,默认使用当前分支 */
target?: string;
/** 标签消息 */
message?: string;
/** 标签注释 */
annotation?: Record<string, any>;
};
/**
* 创建 Blob 参数
*/
type CreateBlobData = {
/** 文件内容 */
content: string;
/** 编码格式,默认: utf-8 */
encoding?: string;
};
/**
* 查询内容参数
*/
type GetContentParams = {
/** Git 引用,分支名、标签名或提交哈希 */
ref?: string;
};
/**
* 查询指定路径内容参数
*/
type GetContentWithPathParams = {
/** Git 引用,分支名、标签名或提交哈希 */
ref?: string;
};
/**
* 获取原始文件参数
*/
type GetRawParams = {
/** 最大 Blob 大小限制(字节) */
max_in_byte?: number;
};
/**
* 设置提交注释参数
*/
type PutCommitAnnotationsData = {
/** 注释键值对 */
annotations: Record<string, string>;
};
/**
* 批量查询提交注释参数
*/
type GetCommitAnnotationsInBatchData = {
/** 提交哈希值列表 */
shas: string[];
};
/**
* 创建提交附件上传 URL 参数
*/
type PostCommitAssetUploadURLData = {
/** 附件名称 */
name: string;
/** 附件路径 */
path: string;
/** 内容长度 */
content_length: number;
/** 内容类型 */
content_type: string;
/** 内容摘要 */
digest: string;
};
/**
* 确认附件上传参数
*/
type PostCommitAssetUploadConfirmationParams = {
/** 附件保持的天数0 表示永久,最大 180 天 */
ttl?: number;
};
/**
* 获取提交附件参数
*/
type GetCommitAssetsParams = {
/** 是否可分享true 表示下载地址有效期 12 小时,最多下载 10 次 */
share?: boolean;
};
/**
* 设置标签注释参数
*/
type PutTagAnnotationsData = {
/** 注释键值对 */
annotations: Record<string, string>;
};

32
test/git.ts Normal file
View File

@@ -0,0 +1,32 @@
import { Git } from '../src/git/index.ts'
import { token, cookie, showMore } from './common.ts';
const git = new Git({ token, cookie });
const repo = 'kevisual/cnb';
const listFiles = async () => {
// const res = await git.getContentWithPath(repo, 'README.md');
// console.log("res", showMore(res));
const res2 = await git.getContentWithPath(repo, 'src/issue');
console.log("res2", showMore(res2));
const res3 = await git.getContentWithPath(repo, 'src/issue/index.ts');
console.log("res3", showMore(res3));
}
// listFiles();
const createBlob = async () => {
const res = await git.createBlob(repo, {
content: 'Hello, CNB!',
encoding: 'utf-8',
});
console.log("createBlob res", showMore(res));
}
createBlob();
const getRaw = async () => {
const res = await git.getRaw(repo, 'main:README.md');
console.log("getRaw res", showMore(res));
}