@canyonjs/git-provider 0.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +49 -0
- package/dist/index.d.mts +78 -0
- package/dist/index.mjs +289 -0
- package/package.json +47 -0
package/README.md
ADDED
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
# git-provider
|
|
2
|
+
|
|
3
|
+
统一封装 GitHub / GitLab / Gitea 的常见仓库 API。
|
|
4
|
+
|
|
5
|
+
## Development
|
|
6
|
+
|
|
7
|
+
- Install dependencies:
|
|
8
|
+
|
|
9
|
+
```bash
|
|
10
|
+
npm install
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
- Run the unit tests:
|
|
14
|
+
|
|
15
|
+
```bash
|
|
16
|
+
npm run test
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
- Build the library:
|
|
20
|
+
|
|
21
|
+
```bash
|
|
22
|
+
npm run build
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
## Usage
|
|
26
|
+
|
|
27
|
+
```ts
|
|
28
|
+
import { createGitProviderClient } from 'git-provider'
|
|
29
|
+
|
|
30
|
+
const client = createGitProviderClient({
|
|
31
|
+
provider: 'gitlab', // 'github' | 'gitlab' | 'gitea'
|
|
32
|
+
token: process.env.GIT_TOKEN
|
|
33
|
+
})
|
|
34
|
+
|
|
35
|
+
// 1) 根据 id 或 owner/repo 获取仓库摘要
|
|
36
|
+
const repo = await client.getRepositorySummary('canyon-project/canyon')
|
|
37
|
+
|
|
38
|
+
// 2) 获取 commit 摘要
|
|
39
|
+
const commit = await client.getCommitSummary('canyon-project/canyon', 'abc123')
|
|
40
|
+
|
|
41
|
+
// 3) 获取单个文件内容
|
|
42
|
+
const file = await client.getFileContent('canyon-project/canyon', 'README.md', 'main')
|
|
43
|
+
|
|
44
|
+
// 4) 获取指定 commit 的 zip 产物
|
|
45
|
+
const archive = await client.downloadArchive('canyon-project/canyon', 'abc123')
|
|
46
|
+
|
|
47
|
+
// 5) 比较两个 commit
|
|
48
|
+
const compare = await client.compareCommits('canyon-project/canyon', 'fromSha', 'toSha')
|
|
49
|
+
```
|
package/dist/index.d.mts
ADDED
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
//#region src/index.d.ts
|
|
2
|
+
type GitProvider = 'github' | 'gitlab' | 'gitea';
|
|
3
|
+
interface GitProviderClientOptions {
|
|
4
|
+
provider: GitProvider;
|
|
5
|
+
token?: string;
|
|
6
|
+
baseUrl?: string;
|
|
7
|
+
headers?: Record<string, string>;
|
|
8
|
+
}
|
|
9
|
+
interface RepositorySummary {
|
|
10
|
+
provider: GitProvider;
|
|
11
|
+
id: string;
|
|
12
|
+
fullName: string;
|
|
13
|
+
name: string;
|
|
14
|
+
defaultBranch?: string;
|
|
15
|
+
webUrl?: string;
|
|
16
|
+
private?: boolean;
|
|
17
|
+
description?: string | null;
|
|
18
|
+
}
|
|
19
|
+
interface CommitSummary {
|
|
20
|
+
provider: GitProvider;
|
|
21
|
+
sha: string;
|
|
22
|
+
shortSha: string;
|
|
23
|
+
title: string;
|
|
24
|
+
message: string;
|
|
25
|
+
authorName?: string;
|
|
26
|
+
authorEmail?: string;
|
|
27
|
+
authoredAt?: string;
|
|
28
|
+
webUrl?: string;
|
|
29
|
+
}
|
|
30
|
+
interface CompareSummary {
|
|
31
|
+
provider: GitProvider;
|
|
32
|
+
fromSha: string;
|
|
33
|
+
toSha: string;
|
|
34
|
+
status?: string;
|
|
35
|
+
aheadBy?: number;
|
|
36
|
+
behindBy?: number;
|
|
37
|
+
totalCommits: number;
|
|
38
|
+
}
|
|
39
|
+
interface FileContentResult {
|
|
40
|
+
provider: GitProvider;
|
|
41
|
+
path: string;
|
|
42
|
+
ref: string;
|
|
43
|
+
sha?: string;
|
|
44
|
+
size?: number;
|
|
45
|
+
content: string;
|
|
46
|
+
}
|
|
47
|
+
interface ArchiveResult {
|
|
48
|
+
provider: GitProvider;
|
|
49
|
+
ref: string;
|
|
50
|
+
contentType?: string | null;
|
|
51
|
+
fileName?: string;
|
|
52
|
+
size: number;
|
|
53
|
+
data: Uint8Array;
|
|
54
|
+
}
|
|
55
|
+
declare class GitProviderClient {
|
|
56
|
+
private readonly provider;
|
|
57
|
+
private readonly token?;
|
|
58
|
+
private readonly baseUrl;
|
|
59
|
+
private readonly extraHeaders;
|
|
60
|
+
constructor(options: GitProviderClientOptions);
|
|
61
|
+
getRepositorySummary(idOrPath: string | number): Promise<RepositorySummary>;
|
|
62
|
+
getCommitSummary(repo: string | number, sha: string): Promise<CommitSummary>;
|
|
63
|
+
compareCommits(repo: string | number, fromSha: string, toSha: string): Promise<CompareSummary>;
|
|
64
|
+
getFileContent(repo: string | number, filePath: string, ref: string): Promise<FileContentResult>;
|
|
65
|
+
downloadArchive(repo: string | number, ref: string): Promise<ArchiveResult>;
|
|
66
|
+
private fetchGiteaProject;
|
|
67
|
+
private resolveOwnerRepo;
|
|
68
|
+
private parseOwnerRepo;
|
|
69
|
+
private encodeGitLabProjectId;
|
|
70
|
+
private encodePath;
|
|
71
|
+
private parseFileNameFromHeaders;
|
|
72
|
+
private requestJson;
|
|
73
|
+
private fetchWithAuth;
|
|
74
|
+
private getAuthHeaders;
|
|
75
|
+
}
|
|
76
|
+
declare function createGitProviderClient(options: GitProviderClientOptions): GitProviderClient;
|
|
77
|
+
//#endregion
|
|
78
|
+
export { ArchiveResult, CommitSummary, CompareSummary, FileContentResult, GitProvider, GitProviderClient, GitProviderClientOptions, RepositorySummary, createGitProviderClient };
|
package/dist/index.mjs
ADDED
|
@@ -0,0 +1,289 @@
|
|
|
1
|
+
//#region src/index.ts
|
|
2
|
+
function stripTrailingSlash(value) {
|
|
3
|
+
return value.endsWith("/") ? value.slice(0, -1) : value;
|
|
4
|
+
}
|
|
5
|
+
function normalizeProviderBaseUrl(provider, baseUrl) {
|
|
6
|
+
if (baseUrl) return stripTrailingSlash(baseUrl);
|
|
7
|
+
if (provider === "github") return "https://api.github.com";
|
|
8
|
+
if (provider === "gitlab") return "https://gitlab.com/api/v4";
|
|
9
|
+
return "https://gitea.com/api/v1";
|
|
10
|
+
}
|
|
11
|
+
function shortSha(sha) {
|
|
12
|
+
return sha.slice(0, 8);
|
|
13
|
+
}
|
|
14
|
+
function decodeBase64ToUtf8(value) {
|
|
15
|
+
return Buffer.from(value.replace(/\n/g, ""), "base64").toString("utf-8");
|
|
16
|
+
}
|
|
17
|
+
function isLikelyNumericRepoId(repo) {
|
|
18
|
+
return typeof repo === "number" || /^\d+$/.test(repo);
|
|
19
|
+
}
|
|
20
|
+
var GitProviderClient = class {
|
|
21
|
+
provider;
|
|
22
|
+
token;
|
|
23
|
+
baseUrl;
|
|
24
|
+
extraHeaders;
|
|
25
|
+
constructor(options) {
|
|
26
|
+
this.provider = options.provider;
|
|
27
|
+
this.token = options.token;
|
|
28
|
+
this.baseUrl = normalizeProviderBaseUrl(options.provider, options.baseUrl);
|
|
29
|
+
this.extraHeaders = options.headers ?? {};
|
|
30
|
+
}
|
|
31
|
+
async getRepositorySummary(idOrPath) {
|
|
32
|
+
if (this.provider === "github") {
|
|
33
|
+
const url = isLikelyNumericRepoId(idOrPath) ? `${this.baseUrl}/repositories/${idOrPath}` : `${this.baseUrl}/repos/${encodeURIComponent(String(idOrPath).split("/")[0])}/${encodeURIComponent(String(idOrPath).split("/")[1] ?? "")}`;
|
|
34
|
+
const project = await this.requestJson(url);
|
|
35
|
+
return {
|
|
36
|
+
provider: this.provider,
|
|
37
|
+
id: String(project.id),
|
|
38
|
+
fullName: project.full_name,
|
|
39
|
+
name: project.name,
|
|
40
|
+
defaultBranch: project.default_branch,
|
|
41
|
+
webUrl: project.html_url,
|
|
42
|
+
private: project.private,
|
|
43
|
+
description: project.description
|
|
44
|
+
};
|
|
45
|
+
}
|
|
46
|
+
if (this.provider === "gitlab") {
|
|
47
|
+
const projectId = this.encodeGitLabProjectId(idOrPath);
|
|
48
|
+
const project = await this.requestJson(`${this.baseUrl}/projects/${projectId}`);
|
|
49
|
+
return {
|
|
50
|
+
provider: this.provider,
|
|
51
|
+
id: String(project.id),
|
|
52
|
+
fullName: project.path_with_namespace,
|
|
53
|
+
name: project.name,
|
|
54
|
+
defaultBranch: project.default_branch,
|
|
55
|
+
webUrl: project.web_url,
|
|
56
|
+
private: project.visibility ? project.visibility !== "public" : void 0,
|
|
57
|
+
description: project.description
|
|
58
|
+
};
|
|
59
|
+
}
|
|
60
|
+
const project = await this.fetchGiteaProject(idOrPath);
|
|
61
|
+
return {
|
|
62
|
+
provider: this.provider,
|
|
63
|
+
id: String(project.id),
|
|
64
|
+
fullName: project.full_name,
|
|
65
|
+
name: project.name,
|
|
66
|
+
defaultBranch: project.default_branch,
|
|
67
|
+
webUrl: project.html_url,
|
|
68
|
+
private: project.private,
|
|
69
|
+
description: project.description
|
|
70
|
+
};
|
|
71
|
+
}
|
|
72
|
+
async getCommitSummary(repo, sha) {
|
|
73
|
+
if (this.provider === "github") {
|
|
74
|
+
const ownerRepo = await this.resolveOwnerRepo(repo);
|
|
75
|
+
const commit = await this.requestJson(`${this.baseUrl}/repos/${encodeURIComponent(ownerRepo.owner)}/${encodeURIComponent(ownerRepo.repo)}/commits/${encodeURIComponent(sha)}`);
|
|
76
|
+
return {
|
|
77
|
+
provider: this.provider,
|
|
78
|
+
sha: commit.sha,
|
|
79
|
+
shortSha: shortSha(commit.sha),
|
|
80
|
+
title: commit.commit?.message?.split("\n")[0] ?? "",
|
|
81
|
+
message: commit.commit?.message ?? "",
|
|
82
|
+
authorName: commit.commit?.author?.name,
|
|
83
|
+
authorEmail: commit.commit?.author?.email,
|
|
84
|
+
authoredAt: commit.commit?.author?.date,
|
|
85
|
+
webUrl: commit.html_url
|
|
86
|
+
};
|
|
87
|
+
}
|
|
88
|
+
if (this.provider === "gitlab") {
|
|
89
|
+
const pid = this.encodeGitLabProjectId(repo);
|
|
90
|
+
const commit = await this.requestJson(`${this.baseUrl}/projects/${pid}/repository/commits/${encodeURIComponent(sha)}`);
|
|
91
|
+
return {
|
|
92
|
+
provider: this.provider,
|
|
93
|
+
sha: commit.id,
|
|
94
|
+
shortSha: shortSha(commit.short_id ?? commit.id),
|
|
95
|
+
title: commit.title ?? commit.message?.split("\n")[0] ?? "",
|
|
96
|
+
message: commit.message ?? "",
|
|
97
|
+
authorName: commit.author_name,
|
|
98
|
+
authorEmail: commit.author_email,
|
|
99
|
+
authoredAt: commit.authored_date,
|
|
100
|
+
webUrl: commit.web_url
|
|
101
|
+
};
|
|
102
|
+
}
|
|
103
|
+
const ownerRepo = await this.resolveOwnerRepo(repo);
|
|
104
|
+
const commit = await this.requestJson(`${this.baseUrl}/repos/${encodeURIComponent(ownerRepo.owner)}/${encodeURIComponent(ownerRepo.repo)}/commits/${encodeURIComponent(sha)}`);
|
|
105
|
+
return {
|
|
106
|
+
provider: this.provider,
|
|
107
|
+
sha: commit.sha,
|
|
108
|
+
shortSha: shortSha(commit.sha),
|
|
109
|
+
title: commit.commit?.message?.split("\n")[0] ?? "",
|
|
110
|
+
message: commit.commit?.message ?? "",
|
|
111
|
+
authorName: commit.commit?.author?.name,
|
|
112
|
+
authorEmail: commit.commit?.author?.email,
|
|
113
|
+
authoredAt: commit.commit?.author?.date,
|
|
114
|
+
webUrl: commit.html_url
|
|
115
|
+
};
|
|
116
|
+
}
|
|
117
|
+
async compareCommits(repo, fromSha, toSha) {
|
|
118
|
+
if (this.provider === "github") {
|
|
119
|
+
const ownerRepo = await this.resolveOwnerRepo(repo);
|
|
120
|
+
const compare = await this.requestJson(`${this.baseUrl}/repos/${encodeURIComponent(ownerRepo.owner)}/${encodeURIComponent(ownerRepo.repo)}/compare/${encodeURIComponent(fromSha)}...${encodeURIComponent(toSha)}`);
|
|
121
|
+
return {
|
|
122
|
+
provider: this.provider,
|
|
123
|
+
fromSha,
|
|
124
|
+
toSha,
|
|
125
|
+
status: compare.status,
|
|
126
|
+
aheadBy: compare.ahead_by,
|
|
127
|
+
behindBy: compare.behind_by,
|
|
128
|
+
totalCommits: compare.total_commits ?? compare.commits?.length ?? 0
|
|
129
|
+
};
|
|
130
|
+
}
|
|
131
|
+
if (this.provider === "gitlab") {
|
|
132
|
+
const pid = this.encodeGitLabProjectId(repo);
|
|
133
|
+
const compare = await this.requestJson(`${this.baseUrl}/projects/${pid}/repository/compare?from=${encodeURIComponent(fromSha)}&to=${encodeURIComponent(toSha)}`);
|
|
134
|
+
return {
|
|
135
|
+
provider: this.provider,
|
|
136
|
+
fromSha,
|
|
137
|
+
toSha,
|
|
138
|
+
status: compare.compare_same_ref ? "identical" : "different",
|
|
139
|
+
totalCommits: compare.commits?.length ?? 0
|
|
140
|
+
};
|
|
141
|
+
}
|
|
142
|
+
const ownerRepo = await this.resolveOwnerRepo(repo);
|
|
143
|
+
const compare = await this.requestJson(`${this.baseUrl}/repos/${encodeURIComponent(ownerRepo.owner)}/${encodeURIComponent(ownerRepo.repo)}/compare/${encodeURIComponent(fromSha)}...${encodeURIComponent(toSha)}`);
|
|
144
|
+
return {
|
|
145
|
+
provider: this.provider,
|
|
146
|
+
fromSha,
|
|
147
|
+
toSha,
|
|
148
|
+
status: compare.status,
|
|
149
|
+
aheadBy: compare.ahead_by,
|
|
150
|
+
behindBy: compare.behind_by,
|
|
151
|
+
totalCommits: compare.total_commits ?? compare.commits?.length ?? 0
|
|
152
|
+
};
|
|
153
|
+
}
|
|
154
|
+
async getFileContent(repo, filePath, ref) {
|
|
155
|
+
if (this.provider === "github") {
|
|
156
|
+
const ownerRepo = await this.resolveOwnerRepo(repo);
|
|
157
|
+
const payload = await this.requestJson(`${this.baseUrl}/repos/${encodeURIComponent(ownerRepo.owner)}/${encodeURIComponent(ownerRepo.repo)}/contents/${this.encodePath(filePath)}?ref=${encodeURIComponent(ref)}`);
|
|
158
|
+
return {
|
|
159
|
+
provider: this.provider,
|
|
160
|
+
path: payload.path ?? filePath,
|
|
161
|
+
ref,
|
|
162
|
+
sha: payload.sha,
|
|
163
|
+
size: payload.size,
|
|
164
|
+
content: decodeBase64ToUtf8(payload.content ?? "")
|
|
165
|
+
};
|
|
166
|
+
}
|
|
167
|
+
if (this.provider === "gitlab") {
|
|
168
|
+
const pid = this.encodeGitLabProjectId(repo);
|
|
169
|
+
const payload = await this.requestJson(`${this.baseUrl}/projects/${pid}/repository/files/${this.encodePath(filePath)}?ref=${encodeURIComponent(ref)}`);
|
|
170
|
+
return {
|
|
171
|
+
provider: this.provider,
|
|
172
|
+
path: payload.file_path ?? filePath,
|
|
173
|
+
ref,
|
|
174
|
+
sha: payload.blob_id,
|
|
175
|
+
size: payload.size,
|
|
176
|
+
content: decodeBase64ToUtf8(payload.content ?? "")
|
|
177
|
+
};
|
|
178
|
+
}
|
|
179
|
+
const ownerRepo = await this.resolveOwnerRepo(repo);
|
|
180
|
+
const payload = await this.requestJson(`${this.baseUrl}/repos/${encodeURIComponent(ownerRepo.owner)}/${encodeURIComponent(ownerRepo.repo)}/contents/${this.encodePath(filePath)}?ref=${encodeURIComponent(ref)}`);
|
|
181
|
+
return {
|
|
182
|
+
provider: this.provider,
|
|
183
|
+
path: payload.path ?? filePath,
|
|
184
|
+
ref,
|
|
185
|
+
sha: payload.sha,
|
|
186
|
+
size: payload.size,
|
|
187
|
+
content: decodeBase64ToUtf8(payload.content ?? "")
|
|
188
|
+
};
|
|
189
|
+
}
|
|
190
|
+
async downloadArchive(repo, ref) {
|
|
191
|
+
let url;
|
|
192
|
+
if (this.provider === "gitlab") {
|
|
193
|
+
const pid = this.encodeGitLabProjectId(repo);
|
|
194
|
+
url = `${this.baseUrl}/projects/${pid}/repository/archive.zip?sha=${encodeURIComponent(ref)}`;
|
|
195
|
+
} else {
|
|
196
|
+
const ownerRepo = await this.resolveOwnerRepo(repo);
|
|
197
|
+
if (this.provider === "github") url = `${this.baseUrl}/repos/${encodeURIComponent(ownerRepo.owner)}/${encodeURIComponent(ownerRepo.repo)}/zipball/${encodeURIComponent(ref)}`;
|
|
198
|
+
else url = `${this.baseUrl}/repos/${encodeURIComponent(ownerRepo.owner)}/${encodeURIComponent(ownerRepo.repo)}/archive/${encodeURIComponent(ref)}.zip`;
|
|
199
|
+
}
|
|
200
|
+
const response = await this.fetchWithAuth(url, { headers: { Accept: "application/zip" } });
|
|
201
|
+
if (!response.ok) {
|
|
202
|
+
const body = await response.text();
|
|
203
|
+
throw new Error(`[${this.provider}] request failed (${response.status}): ${body}`);
|
|
204
|
+
}
|
|
205
|
+
const data = new Uint8Array(await response.arrayBuffer());
|
|
206
|
+
return {
|
|
207
|
+
provider: this.provider,
|
|
208
|
+
ref,
|
|
209
|
+
contentType: response.headers.get("content-type"),
|
|
210
|
+
fileName: this.parseFileNameFromHeaders(response.headers),
|
|
211
|
+
size: data.byteLength,
|
|
212
|
+
data
|
|
213
|
+
};
|
|
214
|
+
}
|
|
215
|
+
async fetchGiteaProject(idOrPath) {
|
|
216
|
+
if (!isLikelyNumericRepoId(idOrPath)) {
|
|
217
|
+
const ownerRepo = this.parseOwnerRepo(String(idOrPath));
|
|
218
|
+
return this.requestJson(`${this.baseUrl}/repos/${encodeURIComponent(ownerRepo.owner)}/${encodeURIComponent(ownerRepo.repo)}`);
|
|
219
|
+
}
|
|
220
|
+
try {
|
|
221
|
+
return await this.requestJson(`${this.baseUrl}/repositories/${idOrPath}`);
|
|
222
|
+
} catch {
|
|
223
|
+
throw new Error("[gitea] numeric repository id not found; try owner/repo form");
|
|
224
|
+
}
|
|
225
|
+
}
|
|
226
|
+
async resolveOwnerRepo(repo) {
|
|
227
|
+
if (!isLikelyNumericRepoId(repo)) return this.parseOwnerRepo(String(repo));
|
|
228
|
+
if (this.provider === "gitlab") {
|
|
229
|
+
const project = await this.getRepositorySummary(repo);
|
|
230
|
+
return this.parseOwnerRepo(project.fullName);
|
|
231
|
+
}
|
|
232
|
+
const project = await this.getRepositorySummary(repo);
|
|
233
|
+
return this.parseOwnerRepo(project.fullName);
|
|
234
|
+
}
|
|
235
|
+
parseOwnerRepo(raw) {
|
|
236
|
+
const parts = raw.split("/");
|
|
237
|
+
if (parts.length < 2 || !parts[0] || !parts[1]) throw new Error(`invalid repository identifier "${raw}", expected "owner/repo" or numeric id`);
|
|
238
|
+
return {
|
|
239
|
+
owner: parts[0],
|
|
240
|
+
repo: parts.slice(1).join("/")
|
|
241
|
+
};
|
|
242
|
+
}
|
|
243
|
+
encodeGitLabProjectId(idOrPath) {
|
|
244
|
+
if (isLikelyNumericRepoId(idOrPath)) return String(idOrPath);
|
|
245
|
+
return this.encodePath(String(idOrPath));
|
|
246
|
+
}
|
|
247
|
+
encodePath(path) {
|
|
248
|
+
return path.split("/").filter(Boolean).map((piece) => encodeURIComponent(piece)).join("%2F");
|
|
249
|
+
}
|
|
250
|
+
parseFileNameFromHeaders(headers) {
|
|
251
|
+
const disposition = headers.get("content-disposition");
|
|
252
|
+
if (!disposition) return;
|
|
253
|
+
const utf8Match = disposition.match(/filename\*=UTF-8''([^;]+)/i);
|
|
254
|
+
if (utf8Match?.[1]) return decodeURIComponent(utf8Match[1]);
|
|
255
|
+
return disposition.match(/filename="([^"]+)"/i)?.[1];
|
|
256
|
+
}
|
|
257
|
+
async requestJson(url) {
|
|
258
|
+
const response = await this.fetchWithAuth(url);
|
|
259
|
+
if (!response.ok) {
|
|
260
|
+
const body = await response.text();
|
|
261
|
+
throw new Error(`[${this.provider}] request failed (${response.status}): ${body}`);
|
|
262
|
+
}
|
|
263
|
+
return response.json();
|
|
264
|
+
}
|
|
265
|
+
async fetchWithAuth(url, init) {
|
|
266
|
+
const headers = new Headers(init?.headers);
|
|
267
|
+
for (const [key, value] of Object.entries(this.getAuthHeaders())) headers.set(key, value);
|
|
268
|
+
for (const [key, value] of Object.entries(this.extraHeaders)) headers.set(key, value);
|
|
269
|
+
return fetch(url, {
|
|
270
|
+
...init,
|
|
271
|
+
headers
|
|
272
|
+
});
|
|
273
|
+
}
|
|
274
|
+
getAuthHeaders() {
|
|
275
|
+
const headers = {};
|
|
276
|
+
if (this.provider === "github") headers.Accept = "application/vnd.github+json";
|
|
277
|
+
else headers.Accept = "application/json";
|
|
278
|
+
if (!this.token) return headers;
|
|
279
|
+
if (this.provider === "gitlab") headers["PRIVATE-TOKEN"] = this.token;
|
|
280
|
+
else if (this.provider === "gitea") headers.Authorization = `token ${this.token}`;
|
|
281
|
+
else headers.Authorization = `Bearer ${this.token}`;
|
|
282
|
+
return headers;
|
|
283
|
+
}
|
|
284
|
+
};
|
|
285
|
+
function createGitProviderClient(options) {
|
|
286
|
+
return new GitProviderClient(options);
|
|
287
|
+
}
|
|
288
|
+
//#endregion
|
|
289
|
+
export { GitProviderClient, createGitProviderClient };
|
package/package.json
ADDED
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@canyonjs/git-provider",
|
|
3
|
+
"type": "module",
|
|
4
|
+
"version": "0.0.1",
|
|
5
|
+
"description": "Unified Git provider client for GitHub, GitLab, and Gitea.",
|
|
6
|
+
"keywords": [
|
|
7
|
+
"git",
|
|
8
|
+
"github",
|
|
9
|
+
"gitlab",
|
|
10
|
+
"gitea",
|
|
11
|
+
"api"
|
|
12
|
+
],
|
|
13
|
+
"author": "canyonjs",
|
|
14
|
+
"license": "MIT",
|
|
15
|
+
"homepage": "https://git.dev.sh.ctripcorp.com/canyon-project/git-provider#readme",
|
|
16
|
+
"repository": {
|
|
17
|
+
"type": "git",
|
|
18
|
+
"url": "git+https://git.dev.sh.ctripcorp.com/canyon-project/git-provider.git"
|
|
19
|
+
},
|
|
20
|
+
"bugs": {
|
|
21
|
+
"url": "https://git.dev.sh.ctripcorp.com/canyon-project/git-provider/issues"
|
|
22
|
+
},
|
|
23
|
+
"types": "./dist/index.d.ts",
|
|
24
|
+
"exports": {
|
|
25
|
+
".": "./dist/index.mjs",
|
|
26
|
+
"./package.json": "./package.json"
|
|
27
|
+
},
|
|
28
|
+
"files": [
|
|
29
|
+
"dist"
|
|
30
|
+
],
|
|
31
|
+
"sideEffects": false,
|
|
32
|
+
"devDependencies": {
|
|
33
|
+
"@types/node": "^25.5.0",
|
|
34
|
+
"@typescript/native-preview": "7.0.0-dev.20260328.1",
|
|
35
|
+
"bumpp": "^11.0.1",
|
|
36
|
+
"tsdown": "^0.21.7",
|
|
37
|
+
"typescript": "^6.0.2",
|
|
38
|
+
"vitest": "^4.1.2"
|
|
39
|
+
},
|
|
40
|
+
"scripts": {
|
|
41
|
+
"build": "tsdown",
|
|
42
|
+
"dev": "tsdown --watch",
|
|
43
|
+
"test": "vitest run",
|
|
44
|
+
"typecheck": "tsc --noEmit",
|
|
45
|
+
"release": "bumpp"
|
|
46
|
+
}
|
|
47
|
+
}
|