@stats-organization/github-readme-stats-core 2.1.4 → 2.2.0
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/build/api/gist.d.ts +2 -7
- package/build/api/gist.d.ts.map +1 -1
- package/build/api/gist.js +28 -26
- package/build/api/index.d.ts +3 -8
- package/build/api/index.d.ts.map +1 -1
- package/build/api/index.js +32 -36
- package/build/api/pin.d.ts +2 -7
- package/build/api/pin.d.ts.map +1 -1
- package/build/api/pin.js +18 -33
- package/build/api/top-langs.d.ts +2 -7
- package/build/api/top-langs.d.ts.map +1 -1
- package/build/api/top-langs.js +32 -44
- package/build/api/wakatime.d.ts +2 -7
- package/build/api/wakatime.d.ts.map +1 -1
- package/build/api/wakatime.js +28 -26
- package/build/calculateRank.d.ts +12 -11
- package/build/calculateRank.d.ts.map +1 -1
- package/build/calculateRank.js +18 -18
- package/build/cards/common-options.d.ts +13 -0
- package/build/cards/common-options.d.ts.map +1 -0
- package/build/cards/common-options.js +1 -0
- package/build/cards/gist.d.ts +11 -16
- package/build/cards/gist.d.ts.map +1 -1
- package/build/cards/gist.js +26 -31
- package/build/cards/repo.d.ts +19 -16
- package/build/cards/repo.d.ts.map +1 -1
- package/build/cards/repo.js +79 -72
- package/build/cards/stats.d.ts +29 -44
- package/build/cards/stats.d.ts.map +1 -1
- package/build/cards/stats.js +118 -173
- package/build/cards/top-languages.d.ts +81 -77
- package/build/cards/top-languages.d.ts.map +1 -1
- package/build/cards/top-languages.js +186 -184
- package/build/cards/wakatime.d.ts +21 -11
- package/build/cards/wakatime.d.ts.map +1 -1
- package/build/cards/wakatime.js +92 -109
- package/build/common/Card.d.ts +41 -14
- package/build/common/Card.d.ts.map +1 -1
- package/build/common/Card.js +92 -31
- package/build/common/I18n.d.ts +4 -2
- package/build/common/I18n.d.ts.map +1 -1
- package/build/common/color.d.ts +91 -15
- package/build/common/color.d.ts.map +1 -1
- package/build/common/color.js +163 -17
- package/build/common/config.d.ts +2 -1
- package/build/common/config.d.ts.map +1 -1
- package/build/common/config.js +16 -26
- package/build/common/constants.d.ts +2 -1
- package/build/common/constants.d.ts.map +1 -1
- package/build/common/date.d.ts +37 -0
- package/build/common/date.d.ts.map +1 -0
- package/build/common/date.js +31 -0
- package/build/common/html.js +1 -1
- package/build/common/http.d.ts +37 -5
- package/build/common/http.d.ts.map +1 -1
- package/build/common/http.js +29 -6
- package/build/common/icons.d.ts +1 -0
- package/build/common/icons.d.ts.map +1 -1
- package/build/common/icons.js +1 -0
- package/build/common/languageColors.d.ts +11 -0
- package/build/common/languageColors.d.ts.map +1 -0
- package/build/common/languageColors.js +15 -0
- package/build/common/languageColors.json +10 -1
- package/build/common/ops.d.ts +27 -33
- package/build/common/ops.d.ts.map +1 -1
- package/build/common/ops.js +31 -48
- package/build/common/render.d.ts +154 -113
- package/build/common/render.d.ts.map +1 -1
- package/build/common/render.js +209 -92
- package/build/common/retryer.d.ts +15 -6
- package/build/common/retryer.d.ts.map +1 -1
- package/build/common/retryer.js +2 -0
- package/build/fetchers/gist.d.ts +6 -21
- package/build/fetchers/gist.d.ts.map +1 -1
- package/build/fetchers/gist.js +28 -64
- package/build/fetchers/repo.d.ts +12 -11
- package/build/fetchers/repo.d.ts.map +1 -1
- package/build/fetchers/repo.js +27 -68
- package/build/fetchers/stats.d.ts +24 -17
- package/build/fetchers/stats.d.ts.map +1 -1
- package/build/fetchers/stats.js +302 -184
- package/build/fetchers/top-languages.d.ts +10 -15
- package/build/fetchers/top-languages.d.ts.map +1 -1
- package/build/fetchers/top-languages.js +52 -103
- package/build/fetchers/types.d.ts +130 -0
- package/build/fetchers/types.d.ts.map +1 -0
- package/build/fetchers/types.js +1 -0
- package/build/fetchers/wakatime.d.ts +9 -5
- package/build/fetchers/wakatime.d.ts.map +1 -1
- package/build/fetchers/wakatime.js +8 -4
- package/build/graphql/contributionsDocument.d.ts +18 -0
- package/build/graphql/contributionsDocument.d.ts.map +1 -0
- package/build/graphql/contributionsDocument.js +30 -0
- package/build/graphql/generated/common.d.ts +42 -0
- package/build/graphql/generated/common.d.ts.map +1 -0
- package/build/graphql/generated/common.js +2 -0
- package/build/graphql/generated/gist.d.ts +44 -0
- package/build/graphql/generated/gist.d.ts.map +1 -0
- package/build/graphql/generated/gist.js +27 -0
- package/build/graphql/generated/repo.d.ts +67 -0
- package/build/graphql/generated/repo.d.ts.map +1 -0
- package/build/graphql/generated/repo.js +30 -0
- package/build/graphql/generated/stats.d.ts +150 -0
- package/build/graphql/generated/stats.d.ts.map +1 -0
- package/build/graphql/generated/stats.js +95 -0
- package/build/graphql/generated/top-languages.d.ts +54 -0
- package/build/graphql/generated/top-languages.d.ts.map +1 -0
- package/build/graphql/generated/top-languages.js +27 -0
- package/build/graphql/graphqlDocument.d.ts +22 -0
- package/build/graphql/graphqlDocument.d.ts.map +1 -0
- package/build/graphql/graphqlDocument.js +8 -0
- package/build/graphql/reposContributedToDocument.d.ts +27 -0
- package/build/graphql/reposContributedToDocument.d.ts.map +1 -0
- package/build/graphql/reposContributedToDocument.js +59 -0
- package/build/index.d.ts +3 -1
- package/build/index.d.ts.map +1 -1
- package/build/index.js +2 -1
- package/build/themes/index.d.ts +32 -0
- package/build/themes/index.d.ts.map +1 -1
- package/build/themes/index.js +28 -0
- package/build/translations.d.ts +17 -0
- package/build/translations.d.ts.map +1 -1
- package/build/translations.js +17 -0
- package/package.json +14 -8
- package/src/_emoji-name-map.d.ts +10 -0
- package/src/_github-username-regex.d.ts +4 -0
- package/src/api/gist.js +31 -31
- package/src/api/index.js +40 -42
- package/src/api/pin.js +20 -38
- package/src/api/top-langs.js +36 -49
- package/src/api/wakatime.js +31 -31
- package/src/{calculateRank.js → calculateRank.ts} +29 -19
- package/src/cards/common-options.ts +13 -0
- package/src/cards/{gist.js → gist.ts} +37 -37
- package/src/cards/{repo.js → repo.ts} +107 -79
- package/src/cards/{stats.js → stats.ts} +173 -210
- package/src/cards/{top-languages.js → top-languages.ts} +325 -243
- package/src/cards/{wakatime.js → wakatime.ts} +158 -127
- package/src/common/Card.ts +123 -43
- package/src/common/I18n.ts +6 -2
- package/src/common/color.ts +240 -28
- package/src/common/config.ts +22 -29
- package/src/common/constants.ts +3 -1
- package/src/common/date.ts +45 -0
- package/src/common/html.ts +1 -1
- package/src/common/http.ts +71 -0
- package/src/common/icons.ts +1 -0
- package/src/common/languageColors.json +10 -1
- package/src/common/languageColors.ts +19 -0
- package/src/common/ops.ts +158 -0
- package/src/common/render.ts +652 -0
- package/src/common/retryer.ts +21 -12
- package/src/fetchers/gist.ts +79 -0
- package/src/fetchers/repo.ts +114 -0
- package/src/fetchers/stats.ts +743 -0
- package/src/fetchers/top-languages.ts +135 -0
- package/src/fetchers/{types.d.ts → types.ts} +28 -20
- package/src/fetchers/{wakatime.js → wakatime.ts} +19 -5
- package/src/graphql/contributionsDocument.ts +44 -0
- package/src/graphql/generated/common.ts +26 -0
- package/src/graphql/generated/gist.ts +59 -0
- package/src/graphql/generated/repo.ts +90 -0
- package/src/graphql/generated/stats.ts +194 -0
- package/src/graphql/generated/top-languages.ts +75 -0
- package/src/graphql/graphqlDocument.ts +25 -0
- package/src/graphql/queries/gist.graphql +25 -0
- package/src/graphql/queries/repo.graphql +28 -0
- package/src/graphql/queries/stats.graphql +120 -0
- package/src/graphql/queries/top-languages.graphql +34 -0
- package/src/graphql/reposContributedToDocument.ts +86 -0
- package/src/index.ts +3 -1
- package/src/themes/index.ts +33 -0
- package/src/translations.ts +17 -0
- package/src/cards/types.d.ts +0 -78
- package/src/common/http.js +0 -19
- package/src/common/ops.js +0 -170
- package/src/common/render.js +0 -440
- package/src/fetchers/gist.js +0 -112
- package/src/fetchers/repo.js +0 -161
- package/src/fetchers/stats.js +0 -474
- package/src/fetchers/top-languages.js +0 -175
- package/src/themes/README.md +0 -229
package/src/common/retryer.ts
CHANGED
|
@@ -5,10 +5,11 @@ import { CustomError } from "./error.js";
|
|
|
5
5
|
import { logger } from "./log.js";
|
|
6
6
|
|
|
7
7
|
/**
|
|
8
|
-
*
|
|
9
|
-
*
|
|
8
|
+
* Error-detection fields the retryer inspects to detect rate-limiting and credential failures.
|
|
9
|
+
* Every fetcher's payload is intersected with
|
|
10
|
+
* this, so the retryer can read `errors`/`message` regardless of the payload's own shape.
|
|
10
11
|
*/
|
|
11
|
-
interface
|
|
12
|
+
interface ResponseErrors {
|
|
12
13
|
errors?: Array<{ type?: string; message?: string }>;
|
|
13
14
|
message?: string;
|
|
14
15
|
}
|
|
@@ -27,27 +28,35 @@ function getRandomInt(max: number): number {
|
|
|
27
28
|
return Math.floor(Math.random() * max);
|
|
28
29
|
}
|
|
29
30
|
|
|
30
|
-
|
|
31
|
+
/**
|
|
32
|
+
* A fetcher's Axios response. `TData` is the shape of `response.data`,
|
|
33
|
+
* which is intersected with {@link ResponseErrors} so the retryer can inspect
|
|
34
|
+
* `errors`/`message`.
|
|
35
|
+
* Defaults to `unknown` (error fields only) for callers that don't care about the payload.
|
|
36
|
+
*/
|
|
37
|
+
type FetcherResponse<TData = unknown> = AxiosResponse<TData & ResponseErrors>;
|
|
31
38
|
|
|
32
|
-
type FetcherFunction = (
|
|
33
|
-
variables:
|
|
39
|
+
type FetcherFunction<TData = unknown, TVariables = Record<string, unknown>> = (
|
|
40
|
+
variables: TVariables,
|
|
34
41
|
token: string,
|
|
35
42
|
retriesForTests?: number,
|
|
36
|
-
) => Promise<FetcherResponse
|
|
43
|
+
) => Promise<FetcherResponse<TData>>;
|
|
37
44
|
|
|
38
45
|
/**
|
|
39
46
|
* Try to execute the fetcher function until it succeeds or the max number of retries is reached.
|
|
40
47
|
*
|
|
48
|
+
* @template TData Shape of `response.data` returned by the fetcher.
|
|
49
|
+
* @template TVariables Variables the fetcher accepts.
|
|
41
50
|
* @param fetcher The fetcher function.
|
|
42
51
|
* @param variables Object with arguments to pass to the fetcher function.
|
|
43
52
|
* @param pat Optional PAT override.
|
|
44
53
|
* @returns The response from the fetcher function.
|
|
45
54
|
*/
|
|
46
|
-
const retryer = async (
|
|
47
|
-
fetcher: FetcherFunction,
|
|
48
|
-
variables:
|
|
55
|
+
const retryer = async <TData = unknown, TVariables = Record<string, unknown>>(
|
|
56
|
+
fetcher: FetcherFunction<TData, TVariables>,
|
|
57
|
+
variables: TVariables,
|
|
49
58
|
pat: string | null = null,
|
|
50
|
-
): Promise<FetcherResponse
|
|
59
|
+
): Promise<FetcherResponse<TData>> => {
|
|
51
60
|
const PATs = pat
|
|
52
61
|
? [{ name: "user PAT from database", value: pat }]
|
|
53
62
|
: getConfig().pats;
|
|
@@ -86,7 +95,7 @@ const retryer = async (
|
|
|
86
95
|
return response;
|
|
87
96
|
}
|
|
88
97
|
} catch (err) {
|
|
89
|
-
const e = err as { response?: FetcherResponse };
|
|
98
|
+
const e = err as { response?: FetcherResponse<TData> };
|
|
90
99
|
|
|
91
100
|
// network/unexpected error → let caller treat as failure
|
|
92
101
|
if (!e.response) {
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
import { MissingParamError } from "../common/error.js";
|
|
2
|
+
import { createGraphQLFetcher } from "../common/http.js";
|
|
3
|
+
import { retryer } from "../common/retryer.js";
|
|
4
|
+
import { GistInfoDocument } from "../graphql/generated/gist.js";
|
|
5
|
+
import type { GistFileInfoFragment } from "../graphql/generated/gist.js";
|
|
6
|
+
|
|
7
|
+
import type { GistData } from "./types.js";
|
|
8
|
+
|
|
9
|
+
const fetcher = createGraphQLFetcher(GistInfoDocument, "token");
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* This function calculates the primary language of a gist by files size.
|
|
13
|
+
*
|
|
14
|
+
* @param files Files.
|
|
15
|
+
* @returns Primary language, or `null` when no file has a language.
|
|
16
|
+
*/
|
|
17
|
+
const calculatePrimaryLanguage = (
|
|
18
|
+
files: Array<GistFileInfoFragment>,
|
|
19
|
+
): string | null => {
|
|
20
|
+
const languages: Record<string, number> = {};
|
|
21
|
+
|
|
22
|
+
for (const file of files) {
|
|
23
|
+
if (file.language) {
|
|
24
|
+
languages[file.language.name] =
|
|
25
|
+
(languages[file.language.name] ?? 0) + (file.size ?? 0);
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
let primaryLanguage: string | null = null;
|
|
30
|
+
let maxSize = -1;
|
|
31
|
+
for (const [language, size] of Object.entries(languages)) {
|
|
32
|
+
if (size > maxSize) {
|
|
33
|
+
maxSize = size;
|
|
34
|
+
primaryLanguage = language;
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
return primaryLanguage;
|
|
39
|
+
};
|
|
40
|
+
|
|
41
|
+
/**
|
|
42
|
+
* Fetch GitHub gist information by given username and ID.
|
|
43
|
+
*
|
|
44
|
+
* @param id GitHub gist ID.
|
|
45
|
+
* @param pat Optional PAT override.
|
|
46
|
+
* @returns Gist data.
|
|
47
|
+
*/
|
|
48
|
+
const fetchGist = async (
|
|
49
|
+
id: string,
|
|
50
|
+
pat: string | null = null,
|
|
51
|
+
): Promise<GistData> => {
|
|
52
|
+
if (!id) {
|
|
53
|
+
throw new MissingParamError(["id"], "/api/gist?id=GIST_ID");
|
|
54
|
+
}
|
|
55
|
+
const res = await retryer(fetcher, { gistName: id }, pat);
|
|
56
|
+
if (res.data.errors) {
|
|
57
|
+
throw new Error(res.data.errors[0]?.message);
|
|
58
|
+
}
|
|
59
|
+
const gist = res.data.data.viewer.gist;
|
|
60
|
+
if (!gist) {
|
|
61
|
+
throw new Error("Gist not found");
|
|
62
|
+
}
|
|
63
|
+
const firstFile = gist.files?.[0];
|
|
64
|
+
if (!firstFile?.name) {
|
|
65
|
+
throw new Error("Gist has no files");
|
|
66
|
+
}
|
|
67
|
+
return {
|
|
68
|
+
name: firstFile.name,
|
|
69
|
+
nameWithOwner: `${gist.owner?.login ?? ""}/${firstFile.name}`,
|
|
70
|
+
description: gist.description,
|
|
71
|
+
language: calculatePrimaryLanguage(
|
|
72
|
+
gist.files?.filter((file) => !!file) ?? [],
|
|
73
|
+
),
|
|
74
|
+
starsCount: gist.stargazerCount,
|
|
75
|
+
forksCount: gist.forks.totalCount,
|
|
76
|
+
};
|
|
77
|
+
};
|
|
78
|
+
|
|
79
|
+
export { fetchGist };
|
|
@@ -0,0 +1,114 @@
|
|
|
1
|
+
import { MissingParamError } from "../common/error.js";
|
|
2
|
+
import { createGraphQLFetcher } from "../common/http.js";
|
|
3
|
+
import { retryer } from "../common/retryer.js";
|
|
4
|
+
import { GetRepoDocument } from "../graphql/generated/repo.js";
|
|
5
|
+
|
|
6
|
+
import { fetchRepoUserStats } from "./stats.js";
|
|
7
|
+
import type { RepositoryData } from "./types.js";
|
|
8
|
+
|
|
9
|
+
const fetcher = createGraphQLFetcher(GetRepoDocument, "token");
|
|
10
|
+
|
|
11
|
+
const urlExample = "/api/pin?username=USERNAME&repo=REPO_NAME";
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
* Fetch repository data.
|
|
15
|
+
*
|
|
16
|
+
* @param username GitHub username.
|
|
17
|
+
* @param reponame GitHub repository name.
|
|
18
|
+
* @param include_prs_authored Include count of PRs authored.
|
|
19
|
+
* @param include_prs_commented Include count of PRs commented.
|
|
20
|
+
* @param include_prs_reviewed Include count of PRs reviewed.
|
|
21
|
+
* @param include_issues_authored Include count of issues authored.
|
|
22
|
+
* @param include_issues_commented Include count of issues commented.
|
|
23
|
+
* @param pat Optional PAT override.
|
|
24
|
+
* @returns Repository data.
|
|
25
|
+
*/
|
|
26
|
+
const fetchRepo = async (
|
|
27
|
+
username: string,
|
|
28
|
+
reponame: string,
|
|
29
|
+
include_prs_authored = false,
|
|
30
|
+
include_prs_commented = false,
|
|
31
|
+
include_prs_reviewed = false,
|
|
32
|
+
include_issues_authored = false,
|
|
33
|
+
include_issues_commented = false,
|
|
34
|
+
pat: string | null = null,
|
|
35
|
+
): Promise<RepositoryData> => {
|
|
36
|
+
let owner = username;
|
|
37
|
+
if (reponame && reponame.includes("/")) {
|
|
38
|
+
const [parsedOwner, parsedRepo] = reponame.split("/");
|
|
39
|
+
owner = parsedOwner ?? "";
|
|
40
|
+
reponame = parsedRepo ?? "";
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
if (owner && !username) {
|
|
44
|
+
username = owner;
|
|
45
|
+
}
|
|
46
|
+
if (username && !owner) {
|
|
47
|
+
owner = username;
|
|
48
|
+
}
|
|
49
|
+
if (!username && !reponame) {
|
|
50
|
+
throw new MissingParamError(["username", "repo"], urlExample);
|
|
51
|
+
}
|
|
52
|
+
if (!username) {
|
|
53
|
+
throw new MissingParamError(["username"], urlExample);
|
|
54
|
+
}
|
|
55
|
+
if (!reponame) {
|
|
56
|
+
throw new MissingParamError(["repo"], urlExample);
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
const res = await retryer(fetcher, { login: owner, repo: reponame }, pat);
|
|
60
|
+
|
|
61
|
+
const data = res.data.data;
|
|
62
|
+
|
|
63
|
+
if (!data.user && !data.organization) {
|
|
64
|
+
throw new Error("Not found");
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
if (data.organization === null && data.user) {
|
|
68
|
+
const repository = data.user.repository;
|
|
69
|
+
if (!repository || repository.isPrivate) {
|
|
70
|
+
throw new Error("User Repository Not found");
|
|
71
|
+
}
|
|
72
|
+
const repoUserStats = await fetchRepoUserStats(
|
|
73
|
+
username,
|
|
74
|
+
[owner + "/" + reponame],
|
|
75
|
+
[],
|
|
76
|
+
include_prs_authored,
|
|
77
|
+
include_prs_commented,
|
|
78
|
+
include_prs_reviewed,
|
|
79
|
+
include_issues_authored,
|
|
80
|
+
include_issues_commented,
|
|
81
|
+
pat,
|
|
82
|
+
);
|
|
83
|
+
return {
|
|
84
|
+
...repoUserStats,
|
|
85
|
+
...repository,
|
|
86
|
+
};
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
if (data.user === null && data.organization) {
|
|
90
|
+
const repository = data.organization.repository;
|
|
91
|
+
if (!repository || repository.isPrivate) {
|
|
92
|
+
throw new Error("Organization Repository Not found");
|
|
93
|
+
}
|
|
94
|
+
const repoUserStats = await fetchRepoUserStats(
|
|
95
|
+
username,
|
|
96
|
+
[owner + "/" + reponame],
|
|
97
|
+
[],
|
|
98
|
+
include_prs_authored,
|
|
99
|
+
include_prs_commented,
|
|
100
|
+
include_prs_reviewed,
|
|
101
|
+
include_issues_authored,
|
|
102
|
+
include_issues_commented,
|
|
103
|
+
pat,
|
|
104
|
+
);
|
|
105
|
+
return {
|
|
106
|
+
...repoUserStats,
|
|
107
|
+
...repository,
|
|
108
|
+
};
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
throw new Error("Unexpected behavior");
|
|
112
|
+
};
|
|
113
|
+
|
|
114
|
+
export { fetchRepo };
|