@lizardbyte/contribkit 2025.315.185528 → 2025.316.4339
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 +38 -6
- package/dist/cli.mjs +2 -1
- package/dist/index.d.mts +74 -1
- package/dist/index.mjs +2 -1
- package/dist/shared/{contribkit.QISHqB4U.mjs → contribkit.CL3hIz1T.mjs} +238 -4
- package/package.json +2 -1
package/README.md
CHANGED
|
@@ -11,18 +11,45 @@ This is a fork of [sponsorkit](https://github.com/antfu-collective/sponsorkit) t
|
|
|
11
11
|
|
|
12
12
|
Supports:
|
|
13
13
|
|
|
14
|
-
-
|
|
15
|
-
- [**
|
|
16
|
-
- [**
|
|
17
|
-
- [**
|
|
18
|
-
-
|
|
19
|
-
- [**
|
|
14
|
+
- Contributors:
|
|
15
|
+
- [**CrowdIn**](https://crowdin.com)
|
|
16
|
+
- [**GitHub**](https://github.com)
|
|
17
|
+
- [**Gitlab**](https://gitlab.com)
|
|
18
|
+
- Sponsors:
|
|
19
|
+
- [**GitHub Sponsors**](https://github.com/sponsors)
|
|
20
|
+
- [**Patreon**](https://www.patreon.com/)
|
|
21
|
+
- [**OpenCollective**](https://opencollective.com/)
|
|
22
|
+
- [**Afdian**](https://afdian.com/)
|
|
23
|
+
- [**Polar**](https://polar.sh/)
|
|
24
|
+
- [**Liberapay**](https://liberapay.com/)
|
|
20
25
|
|
|
21
26
|
## Usage
|
|
22
27
|
|
|
23
28
|
Create `.env` file with:
|
|
24
29
|
|
|
25
30
|
```ini
|
|
31
|
+
;; Contributors
|
|
32
|
+
|
|
33
|
+
; CrowdInContributors provider.
|
|
34
|
+
CONTRIBKIT_CROWDIN_TOKEN=
|
|
35
|
+
CONTRIBKIT_CROWDIN_PROJECT_ID=
|
|
36
|
+
CONTRIBKIT_CROWDIN_MIN_TRANSLATIONS=1
|
|
37
|
+
|
|
38
|
+
; GitHubContributors provider.
|
|
39
|
+
; Token requires the `public_repo` and `read:user` scopes.
|
|
40
|
+
CONTRIBKIT_GITHUB_CONTRIBUTORS_TOKEN=
|
|
41
|
+
CONTRIBKIT_GITHUB_CONTRIBUTORS_LOGIN=
|
|
42
|
+
CONTRIBKIT_GITHUB_CONTRIBUTORS_MIN=1
|
|
43
|
+
CONTRIBKIT_GITHUB_CONTRIBUTORS_REPO=
|
|
44
|
+
|
|
45
|
+
; GitlabContributors provider.
|
|
46
|
+
; Token requires the `read_api` and `read_user` scopes.
|
|
47
|
+
CONTRIBKIT_GITLAB_CONTRIBUTORS_TOKEN=
|
|
48
|
+
CONTRIBKIT_GITLAB_CONTRIBUTORS_MIN=1
|
|
49
|
+
CONTRIBKIT_GITLAB_CONTRIBUTORS_REPO_ID=
|
|
50
|
+
|
|
51
|
+
;; Sponsors
|
|
52
|
+
|
|
26
53
|
; GitHub provider.
|
|
27
54
|
; Token requires the `read:user` and `read:org` scopes.
|
|
28
55
|
CONTRIBKIT_GITHUB_TOKEN=
|
|
@@ -64,6 +91,11 @@ CONTRIBKIT_LIBERAPAY_LOGIN=
|
|
|
64
91
|
|
|
65
92
|
> Only one provider is required to be configured.
|
|
66
93
|
|
|
94
|
+
> ![NOTE]
|
|
95
|
+
> The contributor providers are intended to be separated from each other, unlike the sponsor providers.
|
|
96
|
+
> This will require different env variables to be set for each provider, and to be created from separate
|
|
97
|
+
> commands.
|
|
98
|
+
|
|
67
99
|
Run:
|
|
68
100
|
|
|
69
101
|
```base
|
package/dist/cli.mjs
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import cac from 'cac';
|
|
2
|
-
import { S as SvgComposer, i as generateBadge, p as partitionTiers, t as tierPresets, v as version, l as loadConfig, k as resolveProviders, j as guessProviders, r as resolveAvatars, q as outputFormats, s as svgToPng, g as svgToWebp } from './shared/contribkit.
|
|
2
|
+
import { S as SvgComposer, i as generateBadge, p as partitionTiers, t as tierPresets, v as version, l as loadConfig, k as resolveProviders, j as guessProviders, r as resolveAvatars, q as outputFormats, s as svgToPng, g as svgToWebp } from './shared/contribkit.CL3hIz1T.mjs';
|
|
3
3
|
import fs from 'node:fs';
|
|
4
4
|
import fsp from 'node:fs/promises';
|
|
5
5
|
import { resolve, dirname, relative, join } from 'node:path';
|
|
@@ -12,6 +12,7 @@ import 'dotenv';
|
|
|
12
12
|
import 'ofetch';
|
|
13
13
|
import 'sharp';
|
|
14
14
|
import 'node:crypto';
|
|
15
|
+
import '@crowdin/crowdin-api-client';
|
|
15
16
|
|
|
16
17
|
function notNullish(v) {
|
|
17
18
|
return v != null;
|
package/dist/index.d.mts
CHANGED
|
@@ -83,7 +83,7 @@ interface Sponsorship {
|
|
|
83
83
|
}
|
|
84
84
|
declare const outputFormats: readonly ["svg", "png", "webp", "json"];
|
|
85
85
|
type OutputFormat = typeof outputFormats[number];
|
|
86
|
-
type ProviderName = 'github' | 'patreon' | 'opencollective' | 'afdian' | 'polar' | 'liberapay';
|
|
86
|
+
type ProviderName = 'github' | 'patreon' | 'opencollective' | 'afdian' | 'polar' | 'liberapay' | 'githubContributors' | 'gitlabContributors' | 'crowdinContributors';
|
|
87
87
|
type GitHubAccountType = 'user' | 'organization';
|
|
88
88
|
interface ProvidersConfig {
|
|
89
89
|
github?: {
|
|
@@ -208,6 +208,76 @@ interface ProvidersConfig {
|
|
|
208
208
|
*/
|
|
209
209
|
login?: string;
|
|
210
210
|
};
|
|
211
|
+
githubContributors?: {
|
|
212
|
+
/**
|
|
213
|
+
* User id of your GitHub account.
|
|
214
|
+
*
|
|
215
|
+
* Will read from `CONTRIBKIT_GITHUB_CONTRIBUTORS_LOGIN` environment variable if not set.
|
|
216
|
+
*/
|
|
217
|
+
login?: string;
|
|
218
|
+
/**
|
|
219
|
+
* GitHub Token that have access to your sponsorships.
|
|
220
|
+
*
|
|
221
|
+
* Will read from `CONTRIBKIT_GITHUB_CONTRIBUTORS_TOKEN` environment variable if not set.
|
|
222
|
+
*
|
|
223
|
+
* @deprecated It's not recommended set this value directly, pass from env or use `.env` file.
|
|
224
|
+
*/
|
|
225
|
+
token?: string;
|
|
226
|
+
/**
|
|
227
|
+
* The minimum number of contributions to be considered a sponsor.
|
|
228
|
+
*
|
|
229
|
+
* @default 1
|
|
230
|
+
*/
|
|
231
|
+
minContributions?: number;
|
|
232
|
+
/**
|
|
233
|
+
* The repository to fetch contributors from.
|
|
234
|
+
*
|
|
235
|
+
* Will read from `CONTRIBKIT_GITHUB_CONTRIBUTORS_REPO` environment variable if not set.
|
|
236
|
+
*/
|
|
237
|
+
repo?: string;
|
|
238
|
+
};
|
|
239
|
+
gitlabContributors?: {
|
|
240
|
+
/**
|
|
241
|
+
* Gitlab Token that have access contributors.
|
|
242
|
+
*
|
|
243
|
+
* Will read from `CONTRIBKIT_GITLAB_CONTRIBUTORS_TOKEN` environment variable if not set.
|
|
244
|
+
*
|
|
245
|
+
* @deprecated It's not recommended set this value directly, pass from env or use `.env` file.
|
|
246
|
+
*/
|
|
247
|
+
token?: string;
|
|
248
|
+
/**
|
|
249
|
+
* The minimum number of contributions to be considered a sponsor.
|
|
250
|
+
*
|
|
251
|
+
* @default 1
|
|
252
|
+
*/
|
|
253
|
+
minContributions?: number;
|
|
254
|
+
/**
|
|
255
|
+
* The repository ID to fetch contributors from.
|
|
256
|
+
*
|
|
257
|
+
* Will read from `CONTRIBKIT_GITLAB_CONTRIBUTORS_REPO_ID` environment variable if not set.
|
|
258
|
+
*/
|
|
259
|
+
repoId?: number;
|
|
260
|
+
};
|
|
261
|
+
crowdinContributors?: {
|
|
262
|
+
/**
|
|
263
|
+
* The Crowdin API token.
|
|
264
|
+
*
|
|
265
|
+
* Will read from `CONTRIBKIT_CROWDIN_TOKEN` environment variable if not set.
|
|
266
|
+
*/
|
|
267
|
+
token?: string;
|
|
268
|
+
/**
|
|
269
|
+
* The project id on Crowdin.
|
|
270
|
+
*
|
|
271
|
+
* Will read from `CONTRIBKIT_CROWDIN_PROJECT_ID` environment variable if not set.
|
|
272
|
+
*/
|
|
273
|
+
projectId?: number;
|
|
274
|
+
/**
|
|
275
|
+
* The minimum number of translations to be considered a sponsor.
|
|
276
|
+
*
|
|
277
|
+
* @default 100
|
|
278
|
+
*/
|
|
279
|
+
minTranslations?: number;
|
|
280
|
+
};
|
|
211
281
|
}
|
|
212
282
|
interface ContribkitRenderOptions {
|
|
213
283
|
/**
|
|
@@ -486,6 +556,9 @@ declare const ProvidersMap: {
|
|
|
486
556
|
afdian: Provider;
|
|
487
557
|
polar: Provider;
|
|
488
558
|
liberapay: Provider;
|
|
559
|
+
githubContributors: Provider;
|
|
560
|
+
gitlabContributors: Provider;
|
|
561
|
+
crowdinContributors: Provider;
|
|
489
562
|
};
|
|
490
563
|
declare function guessProviders(config: ContribkitConfig): ProviderName[];
|
|
491
564
|
declare function resolveProviders(names: (ProviderName | Provider)[]): Provider[];
|
package/dist/index.mjs
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
export { F as FALLBACK_AVATAR, G as GitHubProvider, P as ProvidersMap, S as SvgComposer, c as defaultConfig, b as defaultInlineCSS, a as defaultTiers, d as defineConfig, n as fetchGitHubSponsors, m as fetchSponsors, h as genSvgImage, i as generateBadge, j as guessProviders, l as loadConfig, o as makeQuery, q as outputFormats, p as partitionTiers, e as presets, f as resizeImage, r as resolveAvatars, k as resolveProviders, s as svgToPng, g as svgToWebp, t as tierPresets } from './shared/contribkit.
|
|
1
|
+
export { F as FALLBACK_AVATAR, G as GitHubProvider, P as ProvidersMap, S as SvgComposer, c as defaultConfig, b as defaultInlineCSS, a as defaultTiers, d as defineConfig, n as fetchGitHubSponsors, m as fetchSponsors, h as genSvgImage, i as generateBadge, j as guessProviders, l as loadConfig, o as makeQuery, q as outputFormats, p as partitionTiers, e as presets, f as resizeImage, r as resolveAvatars, k as resolveProviders, s as svgToPng, g as svgToWebp, t as tierPresets } from './shared/contribkit.CL3hIz1T.mjs';
|
|
2
2
|
import 'unconfig';
|
|
3
3
|
import 'node:process';
|
|
4
4
|
import 'dotenv';
|
|
@@ -7,3 +7,4 @@ import 'consola';
|
|
|
7
7
|
import 'ofetch';
|
|
8
8
|
import 'sharp';
|
|
9
9
|
import 'node:crypto';
|
|
10
|
+
import '@crowdin/crowdin-api-client';
|
|
@@ -6,6 +6,7 @@ import { consola } from 'consola';
|
|
|
6
6
|
import { $fetch, ofetch } from 'ofetch';
|
|
7
7
|
import sharp from 'sharp';
|
|
8
8
|
import { createHash } from 'node:crypto';
|
|
9
|
+
import { ProjectsGroups, Reports } from '@crowdin/crowdin-api-client';
|
|
9
10
|
|
|
10
11
|
const none = {
|
|
11
12
|
avatar: {
|
|
@@ -179,12 +180,28 @@ function loadEnv() {
|
|
|
179
180
|
liberapay: {
|
|
180
181
|
login: process.env.CONTRIBKIT_LIBERAPAY_LOGIN || process.env.LIBERAPAY_LOGIN
|
|
181
182
|
},
|
|
182
|
-
outputDir: process.env.CONTRIBKIT_DIR
|
|
183
|
+
outputDir: process.env.CONTRIBKIT_DIR,
|
|
184
|
+
githubContributors: {
|
|
185
|
+
login: process.env.CONTRIBKIT_GITHUB_CONTRIBUTORS_LOGIN,
|
|
186
|
+
token: process.env.CONTRIBKIT_GITHUB_CONTRIBUTORS_TOKEN,
|
|
187
|
+
minContributions: Number(process.env.CONTRIBKIT_GITHUB_CONTRIBUTORS_MIN) || 1,
|
|
188
|
+
repo: process.env.CONTRIBKIT_GITHUB_CONTRIBUTORS_REPO
|
|
189
|
+
},
|
|
190
|
+
gitlabContributors: {
|
|
191
|
+
token: process.env.CONTRIBKIT_GITLAB_CONTRIBUTORS_TOKEN,
|
|
192
|
+
minContributions: Number(process.env.CONTRIBKIT_GITLAB_CONTRIBUTORS_MIN) || 1,
|
|
193
|
+
repoId: Number(process.env.CONTRIBKIT_GITLAB_CONTRIBUTORS_REPO_ID)
|
|
194
|
+
},
|
|
195
|
+
crowdinContributors: {
|
|
196
|
+
token: process.env.CONTRIBKIT_CROWDIN_TOKEN,
|
|
197
|
+
projectId: Number(process.env.CONTRIBKIT_CROWDIN_PROJECT_ID),
|
|
198
|
+
minTranslations: Number(process.env.CONTRIBKIT_CROWDIN_MIN_TRANSLATIONS) || 1
|
|
199
|
+
}
|
|
183
200
|
};
|
|
184
201
|
return JSON.parse(JSON.stringify(config));
|
|
185
202
|
}
|
|
186
203
|
|
|
187
|
-
const version = "2025.
|
|
204
|
+
const version = "2025.316.4339";
|
|
188
205
|
|
|
189
206
|
async function fetchImage(url) {
|
|
190
207
|
const arrayBuffer = await $fetch(url, {
|
|
@@ -265,10 +282,16 @@ async function loadConfig(inlineConfig = {}) {
|
|
|
265
282
|
const { config = {} } = await loadConfig$1({
|
|
266
283
|
sources: [
|
|
267
284
|
{
|
|
268
|
-
files: "
|
|
285
|
+
files: "contrib.config"
|
|
269
286
|
},
|
|
270
287
|
{
|
|
271
288
|
files: "contribkit.config"
|
|
289
|
+
},
|
|
290
|
+
{
|
|
291
|
+
files: "sponsor.config"
|
|
292
|
+
},
|
|
293
|
+
{
|
|
294
|
+
files: "sponsorkit.config"
|
|
272
295
|
}
|
|
273
296
|
],
|
|
274
297
|
merge: true
|
|
@@ -503,6 +526,65 @@ function md5(token, params, ts, userId) {
|
|
|
503
526
|
return createHash("md5").update(`${token}params${params}ts${ts}user_id${userId}`).digest("hex");
|
|
504
527
|
}
|
|
505
528
|
|
|
529
|
+
const CrowdinContributorsProvider = {
|
|
530
|
+
name: "crowdinContributors",
|
|
531
|
+
fetchSponsors(config) {
|
|
532
|
+
return fetchCrowdinContributors(
|
|
533
|
+
config.crowdinContributors?.token || config.token,
|
|
534
|
+
config.crowdinContributors?.projectId || 0,
|
|
535
|
+
config.crowdinContributors?.minTranslations || 1
|
|
536
|
+
);
|
|
537
|
+
}
|
|
538
|
+
};
|
|
539
|
+
async function fetchCrowdinContributors(token, projectId, minTranslations = 1) {
|
|
540
|
+
if (!token)
|
|
541
|
+
throw new Error("Crowdin token is required");
|
|
542
|
+
if (!projectId)
|
|
543
|
+
throw new Error("Crowdin project ID is required");
|
|
544
|
+
const credentials = {
|
|
545
|
+
token
|
|
546
|
+
};
|
|
547
|
+
const projectsGroups = new ProjectsGroups(credentials);
|
|
548
|
+
const project = await projectsGroups.getProject(projectId);
|
|
549
|
+
const reports = new Reports(credentials);
|
|
550
|
+
const dateTo = (/* @__PURE__ */ new Date()).toISOString();
|
|
551
|
+
const dateFrom = project.data.createdAt;
|
|
552
|
+
const createReportRequestBody = {
|
|
553
|
+
name: "top-members",
|
|
554
|
+
schema: {
|
|
555
|
+
unit: "words",
|
|
556
|
+
format: "json",
|
|
557
|
+
dateFrom,
|
|
558
|
+
dateTo
|
|
559
|
+
}
|
|
560
|
+
};
|
|
561
|
+
const createReport = await reports.generateReport(projectId, createReportRequestBody);
|
|
562
|
+
await new Promise((resolve) => setTimeout(resolve, 5e3));
|
|
563
|
+
const report = await reports.downloadReport(projectId, createReport.data.identifier);
|
|
564
|
+
const reportRaw = await fetch(report.data.url);
|
|
565
|
+
const reportData = await reportRaw.json();
|
|
566
|
+
const contributors = reportData.data.filter((entry) => entry.translated > minTranslations).map((entry) => ({
|
|
567
|
+
member: entry.user,
|
|
568
|
+
translations: entry.translated
|
|
569
|
+
}));
|
|
570
|
+
return contributors.filter(Boolean).map(({ member, translations }) => ({
|
|
571
|
+
sponsor: {
|
|
572
|
+
type: "User",
|
|
573
|
+
login: member.username,
|
|
574
|
+
name: member.username,
|
|
575
|
+
// fullName is also available
|
|
576
|
+
avatarUrl: member.avatarUrl,
|
|
577
|
+
linkUrl: `https://crowdin.com/profile/${member.username}`
|
|
578
|
+
},
|
|
579
|
+
isOneTime: false,
|
|
580
|
+
monthlyDollars: translations,
|
|
581
|
+
privacyLevel: "PUBLIC",
|
|
582
|
+
tierName: "Translator",
|
|
583
|
+
createdAt: member.joinedAt,
|
|
584
|
+
provider: "crowdinContributors"
|
|
585
|
+
}));
|
|
586
|
+
}
|
|
587
|
+
|
|
506
588
|
// https://developer.mozilla.org/en-US/docs/Web/HTTP/Basics_of_HTTP/Data_URIs
|
|
507
589
|
const DATA_URL_DEFAULT_MIME_TYPE = 'text/plain';
|
|
508
590
|
const DATA_URL_DEFAULT_CHARSET = 'us-ascii';
|
|
@@ -939,6 +1021,149 @@ function makeQuery(login, type, activeOnly = true, cursor) {
|
|
|
939
1021
|
}`;
|
|
940
1022
|
}
|
|
941
1023
|
|
|
1024
|
+
const GitHubContributorsProvider = {
|
|
1025
|
+
name: "githubContributors",
|
|
1026
|
+
fetchSponsors(config) {
|
|
1027
|
+
if (!config.githubContributors?.repo)
|
|
1028
|
+
throw new Error("GitHub repository is required");
|
|
1029
|
+
return fetchGitHubContributors(
|
|
1030
|
+
config.githubContributors?.token || config.token,
|
|
1031
|
+
config.githubContributors?.login || config.login,
|
|
1032
|
+
config.githubContributors.repo,
|
|
1033
|
+
config.githubContributors?.minContributions
|
|
1034
|
+
);
|
|
1035
|
+
}
|
|
1036
|
+
};
|
|
1037
|
+
async function fetchGitHubContributors(token, login, repo, minContributions = 1) {
|
|
1038
|
+
if (!token)
|
|
1039
|
+
throw new Error("GitHub token is required");
|
|
1040
|
+
if (!login)
|
|
1041
|
+
throw new Error("GitHub login is required");
|
|
1042
|
+
if (!repo)
|
|
1043
|
+
throw new Error("GitHub repository is required");
|
|
1044
|
+
const allContributors = [];
|
|
1045
|
+
let page = 1;
|
|
1046
|
+
let hasNextPage = true;
|
|
1047
|
+
while (hasNextPage) {
|
|
1048
|
+
const response = await $fetch(
|
|
1049
|
+
`https://api.github.com/repos/${login}/${repo}/contributors`,
|
|
1050
|
+
{
|
|
1051
|
+
query: {
|
|
1052
|
+
page: String(page),
|
|
1053
|
+
per_page: "100"
|
|
1054
|
+
},
|
|
1055
|
+
headers: {
|
|
1056
|
+
Authorization: `bearer ${token}`,
|
|
1057
|
+
Accept: "application/vnd.github.v3+json"
|
|
1058
|
+
}
|
|
1059
|
+
}
|
|
1060
|
+
);
|
|
1061
|
+
if (!response || !response.length)
|
|
1062
|
+
break;
|
|
1063
|
+
allContributors.push(...response);
|
|
1064
|
+
hasNextPage = response.length === 100;
|
|
1065
|
+
page++;
|
|
1066
|
+
}
|
|
1067
|
+
return allContributors.filter(
|
|
1068
|
+
(contributor) => contributor.type === "User" && contributor.contributions >= minContributions
|
|
1069
|
+
).map((contributor) => ({
|
|
1070
|
+
sponsor: {
|
|
1071
|
+
type: "User",
|
|
1072
|
+
login: contributor.login,
|
|
1073
|
+
name: contributor.login,
|
|
1074
|
+
avatarUrl: contributor.avatar_url,
|
|
1075
|
+
linkUrl: contributor.url
|
|
1076
|
+
},
|
|
1077
|
+
isOneTime: false,
|
|
1078
|
+
monthlyDollars: contributor.contributions,
|
|
1079
|
+
privacyLevel: "PUBLIC",
|
|
1080
|
+
tierName: "Contributor",
|
|
1081
|
+
createdAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
1082
|
+
provider: "githubContributors"
|
|
1083
|
+
}));
|
|
1084
|
+
}
|
|
1085
|
+
|
|
1086
|
+
const GitlabContributorsProvider = {
|
|
1087
|
+
name: "gitlabContributors",
|
|
1088
|
+
fetchSponsors(config) {
|
|
1089
|
+
if (!config.gitlabContributors?.repoId)
|
|
1090
|
+
throw new Error("Gitlab repoId is required");
|
|
1091
|
+
return fetchGitlabContributors(
|
|
1092
|
+
config.gitlabContributors?.token || config.token,
|
|
1093
|
+
config.gitlabContributors.repoId,
|
|
1094
|
+
config.gitlabContributors?.minContributions
|
|
1095
|
+
);
|
|
1096
|
+
}
|
|
1097
|
+
};
|
|
1098
|
+
async function fetchGitlabContributors(token, repoId, minContributions = 1) {
|
|
1099
|
+
if (!token)
|
|
1100
|
+
throw new Error("Gitlab token is required");
|
|
1101
|
+
if (!repoId)
|
|
1102
|
+
throw new Error("Gitlab repoId is required");
|
|
1103
|
+
const allContributors = [];
|
|
1104
|
+
let page = 1;
|
|
1105
|
+
let hasNextPage = true;
|
|
1106
|
+
while (hasNextPage) {
|
|
1107
|
+
const response = await $fetch(
|
|
1108
|
+
`https://gitlab.com/api/v4/projects/${repoId}/repository/contributors`,
|
|
1109
|
+
{
|
|
1110
|
+
query: {
|
|
1111
|
+
page: String(page),
|
|
1112
|
+
per_page: "100",
|
|
1113
|
+
sort: "desc"
|
|
1114
|
+
},
|
|
1115
|
+
headers: {
|
|
1116
|
+
"PRIVATE-TOKEN": token,
|
|
1117
|
+
"Content-Type": "application/json"
|
|
1118
|
+
}
|
|
1119
|
+
}
|
|
1120
|
+
);
|
|
1121
|
+
if (!response || !response.length)
|
|
1122
|
+
break;
|
|
1123
|
+
allContributors.push(...response);
|
|
1124
|
+
hasNextPage = response.length === 100;
|
|
1125
|
+
page++;
|
|
1126
|
+
}
|
|
1127
|
+
const sponsorships = [];
|
|
1128
|
+
for (const contributor of allContributors) {
|
|
1129
|
+
if (contributor.commits < minContributions)
|
|
1130
|
+
continue;
|
|
1131
|
+
try {
|
|
1132
|
+
const userDetails = await $fetch("https://gitlab.com/api/v4/users", {
|
|
1133
|
+
query: {
|
|
1134
|
+
search: contributor.email
|
|
1135
|
+
},
|
|
1136
|
+
headers: {
|
|
1137
|
+
"PRIVATE-TOKEN": token,
|
|
1138
|
+
"Content-Type": "application/json"
|
|
1139
|
+
}
|
|
1140
|
+
});
|
|
1141
|
+
if (userDetails && userDetails.length > 0) {
|
|
1142
|
+
const user = userDetails[0];
|
|
1143
|
+
sponsorships.push({
|
|
1144
|
+
sponsor: {
|
|
1145
|
+
type: "User",
|
|
1146
|
+
login: user.username,
|
|
1147
|
+
name: user.username,
|
|
1148
|
+
// user.name is also available
|
|
1149
|
+
avatarUrl: user.avatar_url,
|
|
1150
|
+
linkUrl: user.web_url
|
|
1151
|
+
},
|
|
1152
|
+
isOneTime: false,
|
|
1153
|
+
monthlyDollars: contributor.commits,
|
|
1154
|
+
privacyLevel: "PUBLIC",
|
|
1155
|
+
tierName: "Contributor",
|
|
1156
|
+
createdAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
1157
|
+
provider: "gitlabContributors"
|
|
1158
|
+
});
|
|
1159
|
+
}
|
|
1160
|
+
} catch (error) {
|
|
1161
|
+
console.warn(`Failed to fetch user details for ${contributor.email}:`, error);
|
|
1162
|
+
}
|
|
1163
|
+
}
|
|
1164
|
+
return sponsorships;
|
|
1165
|
+
}
|
|
1166
|
+
|
|
942
1167
|
const LiberapayProvider = {
|
|
943
1168
|
name: "liberapay",
|
|
944
1169
|
fetchSponsors(config) {
|
|
@@ -1409,7 +1634,10 @@ const ProvidersMap = {
|
|
|
1409
1634
|
opencollective: OpenCollectiveProvider,
|
|
1410
1635
|
afdian: AfdianProvider,
|
|
1411
1636
|
polar: PolarProvider,
|
|
1412
|
-
liberapay: LiberapayProvider
|
|
1637
|
+
liberapay: LiberapayProvider,
|
|
1638
|
+
githubContributors: GitHubContributorsProvider,
|
|
1639
|
+
gitlabContributors: GitlabContributorsProvider,
|
|
1640
|
+
crowdinContributors: CrowdinContributorsProvider
|
|
1413
1641
|
};
|
|
1414
1642
|
function guessProviders(config) {
|
|
1415
1643
|
const items = [];
|
|
@@ -1425,6 +1653,12 @@ function guessProviders(config) {
|
|
|
1425
1653
|
items.push("polar");
|
|
1426
1654
|
if (config.liberapay && config.liberapay.login)
|
|
1427
1655
|
items.push("liberapay");
|
|
1656
|
+
if (config.githubContributors?.login && config.githubContributors?.token)
|
|
1657
|
+
items.push("githubContributors");
|
|
1658
|
+
if (config.gitlabContributors?.token && config.gitlabContributors?.repoId)
|
|
1659
|
+
items.push("gitlabContributors");
|
|
1660
|
+
if (config.crowdinContributors?.token && config.crowdinContributors?.projectId)
|
|
1661
|
+
items.push("crowdinContributors");
|
|
1428
1662
|
if (!items.length)
|
|
1429
1663
|
items.push("github");
|
|
1430
1664
|
return items;
|
package/package.json
CHANGED
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
"type": "git",
|
|
6
6
|
"url": "git+https://github.com/LizardByte/contribkit.git"
|
|
7
7
|
},
|
|
8
|
-
"version": "2025.
|
|
8
|
+
"version": "2025.316.4339",
|
|
9
9
|
"description": "Toolkit for generating contributor images",
|
|
10
10
|
"license": "MIT",
|
|
11
11
|
"funding": "https://app.lizardbyte.dev",
|
|
@@ -46,6 +46,7 @@
|
|
|
46
46
|
"release": "bumpp && pnpm publish"
|
|
47
47
|
},
|
|
48
48
|
"dependencies": {
|
|
49
|
+
"@crowdin/crowdin-api-client": "^1.41.2",
|
|
49
50
|
"ansis": "^3.17.0",
|
|
50
51
|
"cac": "^6.7.14",
|
|
51
52
|
"consola": "^3.4.0",
|