generated from nhcarrigan/template
### Explanation This gets us in line with our other project standards, and allows us to start testing! ### Issue Closes #18 ### Attestations - [x] I have read and agree to the [Code of Conduct](https://docs.nhcarrigan.com/community/coc/) - [x] I have read and agree to the [Community Guidelines](https://docs.nhcarrigan.com/community/guide/). - [x] My contribution complies with the [Contributor Covenant](https://docs.nhcarrigan.com/dev/covenant/). ### Dependencies - [x] I have pinned the dependencies to a specific patch version. ### Style - [x] I have run the linter and resolved any errors. - [x] My pull request uses an appropriate title, matching the conventional commit standards. - [x] My scope of feat/fix/chore/etc. correctly matches the nature of changes in my pull request. ### Tests - [ ] My contribution adds new code, and I have added tests to cover it. - [ ] My contribution modifies existing code, and I have updated the tests to reflect these changes. - [ ] All new and existing tests pass locally with my changes. - [ ] Code coverage remains at or above the configured threshold. ### Documentation _No response_ ### Versioning Major - My pull request introduces a breaking change. Reviewed-on: https://codeberg.org/nhcarrigan/portfolio/pulls/34 Co-authored-by: Naomi Carrigan <commits@nhcarrigan.com> Co-committed-by: Naomi Carrigan <commits@nhcarrigan.com>
734 lines
20 KiB
TypeScript
734 lines
20 KiB
TypeScript
/**
|
|
* @copyright nhcarrigan
|
|
* @license Naomi's Public License
|
|
* @author Naomi Carrigan
|
|
*/
|
|
interface ActivityData {
|
|
id: string;
|
|
type: string;
|
|
actor: Actor;
|
|
repo: Repo;
|
|
payload: Payload;
|
|
public: boolean;
|
|
created_at: string;
|
|
}
|
|
|
|
interface Actor {
|
|
id: number;
|
|
login: string;
|
|
display_login: string;
|
|
gravatar_id: string;
|
|
url: string;
|
|
avatar_url: string;
|
|
}
|
|
|
|
interface Repo {
|
|
id: number;
|
|
name: string;
|
|
url: string;
|
|
}
|
|
|
|
interface Payload {
|
|
repository_id?: number;
|
|
push_id?: number;
|
|
size?: number;
|
|
distinct_size?: number;
|
|
ref?: string;
|
|
head?: string;
|
|
before?: string;
|
|
commits?: Array<Commit>;
|
|
ref_type?: string;
|
|
pusher_type?: string;
|
|
action?: string;
|
|
number?: number;
|
|
pull_request?: PullRequest;
|
|
review?: Review;
|
|
issue?: Issue2;
|
|
comment?: Comment;
|
|
}
|
|
|
|
interface Commit {
|
|
sha: string;
|
|
author: Author;
|
|
message: string;
|
|
distinct: boolean;
|
|
url: string;
|
|
}
|
|
|
|
interface Author {
|
|
email: string;
|
|
name: string;
|
|
}
|
|
|
|
interface PullRequest {
|
|
url: string;
|
|
id: number;
|
|
node_id: string;
|
|
html_url: string;
|
|
diff_url: string;
|
|
patch_url: string;
|
|
issue_url: string;
|
|
number: number;
|
|
state: string;
|
|
locked: boolean;
|
|
title: string;
|
|
user: User;
|
|
body?: string;
|
|
created_at: string;
|
|
updated_at: string;
|
|
closed_at?: string;
|
|
merged_at?: string;
|
|
merge_commit_sha: string;
|
|
assignee: unknown;
|
|
assignees: Array<unknown>;
|
|
requested_reviewers: Array<unknown>;
|
|
requested_teams: Array<unknown>;
|
|
labels: Array<Label>;
|
|
milestone: unknown;
|
|
draft: boolean;
|
|
commits_url: string;
|
|
review_comments_url: string;
|
|
review_comment_url: string;
|
|
comments_url: string;
|
|
statuses_url: string;
|
|
head: Head;
|
|
base: Base;
|
|
_links: Links;
|
|
author_association: string;
|
|
auto_merge: unknown;
|
|
active_lock_reason: unknown;
|
|
merged?: boolean;
|
|
mergeable: unknown;
|
|
rebaseable: unknown;
|
|
mergeable_state?: string;
|
|
merged_by?: MergedBy;
|
|
comments?: number;
|
|
review_comments?: number;
|
|
maintainer_can_modify?: boolean;
|
|
commits?: number;
|
|
additions?: number;
|
|
deletions?: number;
|
|
changed_files?: number;
|
|
}
|
|
|
|
interface User {
|
|
login: string;
|
|
id: number;
|
|
node_id: string;
|
|
avatar_url: string;
|
|
gravatar_id: string;
|
|
url: string;
|
|
html_url: string;
|
|
followers_url: string;
|
|
following_url: string;
|
|
gists_url: string;
|
|
starred_url: string;
|
|
subscriptions_url: string;
|
|
organizations_url: string;
|
|
repos_url: string;
|
|
events_url: string;
|
|
received_events_url: string;
|
|
type: string;
|
|
site_admin: boolean;
|
|
}
|
|
|
|
interface Label {
|
|
id: number;
|
|
node_id: string;
|
|
url: string;
|
|
name: string;
|
|
color: string;
|
|
default: boolean;
|
|
description: string;
|
|
}
|
|
|
|
interface Head {
|
|
label: string;
|
|
ref: string;
|
|
sha: string;
|
|
user: User2;
|
|
repo: Repo2;
|
|
}
|
|
|
|
interface User2 {
|
|
login: string;
|
|
id: number;
|
|
node_id: string;
|
|
avatar_url: string;
|
|
gravatar_id: string;
|
|
url: string;
|
|
html_url: string;
|
|
followers_url: string;
|
|
following_url: string;
|
|
gists_url: string;
|
|
starred_url: string;
|
|
subscriptions_url: string;
|
|
organizations_url: string;
|
|
repos_url: string;
|
|
events_url: string;
|
|
received_events_url: string;
|
|
type: string;
|
|
site_admin: boolean;
|
|
}
|
|
|
|
interface Repo2 {
|
|
id: number;
|
|
node_id: string;
|
|
name: string;
|
|
full_name: string;
|
|
private: boolean;
|
|
owner: Owner;
|
|
html_url: string;
|
|
description: string;
|
|
fork: boolean;
|
|
url: string;
|
|
forks_url: string;
|
|
keys_url: string;
|
|
collaborators_url: string;
|
|
teams_url: string;
|
|
hooks_url: string;
|
|
issue_events_url: string;
|
|
events_url: string;
|
|
assignees_url: string;
|
|
branches_url: string;
|
|
tags_url: string;
|
|
blobs_url: string;
|
|
git_tags_url: string;
|
|
git_refs_url: string;
|
|
trees_url: string;
|
|
statuses_url: string;
|
|
languages_url: string;
|
|
stargazers_url: string;
|
|
contributors_url: string;
|
|
subscribers_url: string;
|
|
subscription_url: string;
|
|
commits_url: string;
|
|
git_commits_url: string;
|
|
comments_url: string;
|
|
issue_comment_url: string;
|
|
contents_url: string;
|
|
compare_url: string;
|
|
merges_url: string;
|
|
archive_url: string;
|
|
downloads_url: string;
|
|
issues_url: string;
|
|
pulls_url: string;
|
|
milestones_url: string;
|
|
notifications_url: string;
|
|
labels_url: string;
|
|
releases_url: string;
|
|
deployments_url: string;
|
|
created_at: string;
|
|
updated_at: string;
|
|
pushed_at: string;
|
|
git_url: string;
|
|
ssh_url: string;
|
|
clone_url: string;
|
|
svn_url: string;
|
|
homepage: string;
|
|
size: number;
|
|
stargazers_count: number;
|
|
watchers_count: number;
|
|
language: string;
|
|
has_issues: boolean;
|
|
has_projects: boolean;
|
|
has_downloads: boolean;
|
|
has_wiki: boolean;
|
|
has_pages: boolean;
|
|
has_discussions: boolean;
|
|
forks_count: number;
|
|
mirror_url: unknown;
|
|
archived: boolean;
|
|
disabled: boolean;
|
|
open_issues_count: number;
|
|
license: License;
|
|
allow_forking: boolean;
|
|
is_template: boolean;
|
|
web_commit_signoff_required: boolean;
|
|
topics: Array<string>;
|
|
visibility: string;
|
|
forks: number;
|
|
open_issues: number;
|
|
watchers: number;
|
|
default_branch: string;
|
|
}
|
|
|
|
interface Owner {
|
|
login: string;
|
|
id: number;
|
|
node_id: string;
|
|
avatar_url: string;
|
|
gravatar_id: string;
|
|
url: string;
|
|
html_url: string;
|
|
followers_url: string;
|
|
following_url: string;
|
|
gists_url: string;
|
|
starred_url: string;
|
|
subscriptions_url: string;
|
|
organizations_url: string;
|
|
repos_url: string;
|
|
events_url: string;
|
|
received_events_url: string;
|
|
type: string;
|
|
site_admin: boolean;
|
|
}
|
|
|
|
interface License {
|
|
key: string;
|
|
name: string;
|
|
spdx_id: string;
|
|
url: string;
|
|
node_id: string;
|
|
}
|
|
|
|
interface Base {
|
|
label: string;
|
|
ref: string;
|
|
sha: string;
|
|
user: User3;
|
|
repo: Repo3;
|
|
}
|
|
|
|
interface User3 {
|
|
login: string;
|
|
id: number;
|
|
node_id: string;
|
|
avatar_url: string;
|
|
gravatar_id: string;
|
|
url: string;
|
|
html_url: string;
|
|
followers_url: string;
|
|
following_url: string;
|
|
gists_url: string;
|
|
starred_url: string;
|
|
subscriptions_url: string;
|
|
organizations_url: string;
|
|
repos_url: string;
|
|
events_url: string;
|
|
received_events_url: string;
|
|
type: string;
|
|
site_admin: boolean;
|
|
}
|
|
|
|
interface Repo3 {
|
|
id: number;
|
|
node_id: string;
|
|
name: string;
|
|
full_name: string;
|
|
private: boolean;
|
|
owner: Owner2;
|
|
html_url: string;
|
|
description: string;
|
|
fork: boolean;
|
|
url: string;
|
|
forks_url: string;
|
|
keys_url: string;
|
|
collaborators_url: string;
|
|
teams_url: string;
|
|
hooks_url: string;
|
|
issue_events_url: string;
|
|
events_url: string;
|
|
assignees_url: string;
|
|
branches_url: string;
|
|
tags_url: string;
|
|
blobs_url: string;
|
|
git_tags_url: string;
|
|
git_refs_url: string;
|
|
trees_url: string;
|
|
statuses_url: string;
|
|
languages_url: string;
|
|
stargazers_url: string;
|
|
contributors_url: string;
|
|
subscribers_url: string;
|
|
subscription_url: string;
|
|
commits_url: string;
|
|
git_commits_url: string;
|
|
comments_url: string;
|
|
issue_comment_url: string;
|
|
contents_url: string;
|
|
compare_url: string;
|
|
merges_url: string;
|
|
archive_url: string;
|
|
downloads_url: string;
|
|
issues_url: string;
|
|
pulls_url: string;
|
|
milestones_url: string;
|
|
notifications_url: string;
|
|
labels_url: string;
|
|
releases_url: string;
|
|
deployments_url: string;
|
|
created_at: string;
|
|
updated_at: string;
|
|
pushed_at: string;
|
|
git_url: string;
|
|
ssh_url: string;
|
|
clone_url: string;
|
|
svn_url: string;
|
|
homepage: string;
|
|
size: number;
|
|
stargazers_count: number;
|
|
watchers_count: number;
|
|
language: string;
|
|
has_issues: boolean;
|
|
has_projects: boolean;
|
|
has_downloads: boolean;
|
|
has_wiki: boolean;
|
|
has_pages: boolean;
|
|
has_discussions: boolean;
|
|
forks_count: number;
|
|
mirror_url: unknown;
|
|
archived: boolean;
|
|
disabled: boolean;
|
|
open_issues_count: number;
|
|
license: License2;
|
|
allow_forking: boolean;
|
|
is_template: boolean;
|
|
web_commit_signoff_required: boolean;
|
|
topics: Array<string>;
|
|
visibility: string;
|
|
forks: number;
|
|
open_issues: number;
|
|
watchers: number;
|
|
default_branch: string;
|
|
}
|
|
|
|
interface Owner2 {
|
|
login: string;
|
|
id: number;
|
|
node_id: string;
|
|
avatar_url: string;
|
|
gravatar_id: string;
|
|
url: string;
|
|
html_url: string;
|
|
followers_url: string;
|
|
following_url: string;
|
|
gists_url: string;
|
|
starred_url: string;
|
|
subscriptions_url: string;
|
|
organizations_url: string;
|
|
repos_url: string;
|
|
events_url: string;
|
|
received_events_url: string;
|
|
type: string;
|
|
site_admin: boolean;
|
|
}
|
|
|
|
interface License2 {
|
|
key: string;
|
|
name: string;
|
|
spdx_id: string;
|
|
url: string;
|
|
node_id: string;
|
|
}
|
|
|
|
interface Links {
|
|
self: Self;
|
|
html: Html;
|
|
issue: Issue;
|
|
comments: Comments;
|
|
review_comments: ReviewComments;
|
|
review_comment: ReviewComment;
|
|
commits: Commits;
|
|
statuses: Statuses;
|
|
}
|
|
|
|
interface Self {
|
|
href: string;
|
|
}
|
|
|
|
interface Html {
|
|
href: string;
|
|
}
|
|
|
|
interface Issue {
|
|
href: string;
|
|
}
|
|
|
|
interface Comments {
|
|
href: string;
|
|
}
|
|
|
|
interface ReviewComments {
|
|
href: string;
|
|
}
|
|
|
|
interface ReviewComment {
|
|
href: string;
|
|
}
|
|
|
|
interface Commits {
|
|
href: string;
|
|
}
|
|
|
|
interface Statuses {
|
|
href: string;
|
|
}
|
|
|
|
interface MergedBy {
|
|
login: string;
|
|
id: number;
|
|
node_id: string;
|
|
avatar_url: string;
|
|
gravatar_id: string;
|
|
url: string;
|
|
html_url: string;
|
|
followers_url: string;
|
|
following_url: string;
|
|
gists_url: string;
|
|
starred_url: string;
|
|
subscriptions_url: string;
|
|
organizations_url: string;
|
|
repos_url: string;
|
|
events_url: string;
|
|
received_events_url: string;
|
|
type: string;
|
|
site_admin: boolean;
|
|
}
|
|
|
|
interface Review {
|
|
id: number;
|
|
node_id: string;
|
|
user: User4;
|
|
body: unknown;
|
|
commit_id: string;
|
|
submitted_at: string;
|
|
state: string;
|
|
html_url: string;
|
|
pull_request_url: string;
|
|
author_association: string;
|
|
_links: Links2;
|
|
}
|
|
|
|
interface User4 {
|
|
login: string;
|
|
id: number;
|
|
node_id: string;
|
|
avatar_url: string;
|
|
gravatar_id: string;
|
|
url: string;
|
|
html_url: string;
|
|
followers_url: string;
|
|
following_url: string;
|
|
gists_url: string;
|
|
starred_url: string;
|
|
subscriptions_url: string;
|
|
organizations_url: string;
|
|
repos_url: string;
|
|
events_url: string;
|
|
received_events_url: string;
|
|
type: string;
|
|
site_admin: boolean;
|
|
}
|
|
|
|
interface Links2 {
|
|
html: Html2;
|
|
pull_request: PullRequest2;
|
|
}
|
|
|
|
interface Html2 {
|
|
href: string;
|
|
}
|
|
|
|
interface PullRequest2 {
|
|
href: string;
|
|
}
|
|
|
|
interface Issue2 {
|
|
url: string;
|
|
repository_url: string;
|
|
labels_url: string;
|
|
comments_url: string;
|
|
events_url: string;
|
|
html_url: string;
|
|
id: number;
|
|
node_id: string;
|
|
number: number;
|
|
title: string;
|
|
user: User5;
|
|
labels: Array<Label2>;
|
|
state: string;
|
|
locked: boolean;
|
|
assignee: unknown;
|
|
assignees: Array<unknown>;
|
|
milestone: unknown;
|
|
comments: number;
|
|
created_at: string;
|
|
updated_at: string;
|
|
closed_at?: string;
|
|
author_association: string;
|
|
active_lock_reason: unknown;
|
|
body: string;
|
|
reactions: Reactions;
|
|
timeline_url: string;
|
|
performed_via_github_app: unknown;
|
|
state_reason?: string;
|
|
}
|
|
|
|
interface User5 {
|
|
login: string;
|
|
id: number;
|
|
node_id: string;
|
|
avatar_url: string;
|
|
gravatar_id: string;
|
|
url: string;
|
|
html_url: string;
|
|
followers_url: string;
|
|
following_url: string;
|
|
gists_url: string;
|
|
starred_url: string;
|
|
subscriptions_url: string;
|
|
organizations_url: string;
|
|
repos_url: string;
|
|
events_url: string;
|
|
received_events_url: string;
|
|
type: string;
|
|
site_admin: boolean;
|
|
}
|
|
|
|
interface Label2 {
|
|
id: number;
|
|
node_id: string;
|
|
url: string;
|
|
name: string;
|
|
color: string;
|
|
default: boolean;
|
|
description: string;
|
|
}
|
|
|
|
interface Reactions {
|
|
"url": string;
|
|
"total_count": number;
|
|
"+1": number;
|
|
"-1": number;
|
|
"laugh": number;
|
|
"hooray": number;
|
|
"confused": number;
|
|
"heart": number;
|
|
"rocket": number;
|
|
"eyes": number;
|
|
}
|
|
|
|
interface Comment {
|
|
url: string;
|
|
html_url: string;
|
|
issue_url?: string;
|
|
id: number;
|
|
node_id: string;
|
|
user: User6;
|
|
created_at: string;
|
|
updated_at: string;
|
|
author_association: string;
|
|
body: string;
|
|
reactions: Reactions2;
|
|
performed_via_github_app: unknown;
|
|
pull_request_review_id?: number;
|
|
diff_hunk?: string;
|
|
path?: string;
|
|
commit_id?: string;
|
|
original_commit_id?: string;
|
|
pull_request_url?: string;
|
|
_links?: Links3;
|
|
start_line?: number;
|
|
original_start_line?: number;
|
|
start_side?: string;
|
|
line?: number;
|
|
original_line?: number;
|
|
side?: string;
|
|
in_reply_to_id?: number;
|
|
original_position?: number;
|
|
position?: number;
|
|
subject_type?: string;
|
|
}
|
|
|
|
interface User6 {
|
|
login: string;
|
|
id: number;
|
|
node_id: string;
|
|
avatar_url: string;
|
|
gravatar_id: string;
|
|
url: string;
|
|
html_url: string;
|
|
followers_url: string;
|
|
following_url: string;
|
|
gists_url: string;
|
|
starred_url: string;
|
|
subscriptions_url: string;
|
|
organizations_url: string;
|
|
repos_url: string;
|
|
events_url: string;
|
|
received_events_url: string;
|
|
type: string;
|
|
site_admin: boolean;
|
|
}
|
|
|
|
interface Reactions2 {
|
|
"url": string;
|
|
"total_count": number;
|
|
"+1": number;
|
|
"-1": number;
|
|
"laugh": number;
|
|
"hooray": number;
|
|
"confused": number;
|
|
"heart": number;
|
|
"rocket": number;
|
|
"eyes": number;
|
|
}
|
|
|
|
interface Links3 {
|
|
self: Self2;
|
|
html: Html3;
|
|
pull_request: PullRequest3;
|
|
}
|
|
|
|
interface Self2 {
|
|
href: string;
|
|
}
|
|
|
|
interface Html3 {
|
|
href: string;
|
|
}
|
|
|
|
interface PullRequest3 {
|
|
href: string;
|
|
}
|
|
|
|
class Github {
|
|
private cache: Array<ActivityData>;
|
|
private lastUpdate: Date | null = null;
|
|
public constructor() {
|
|
this.cache = [];
|
|
}
|
|
|
|
public async getActivities(): Promise<Array<ActivityData>> {
|
|
// Stale after 1 hour
|
|
if (this.lastUpdate && Date.now()
|
|
- this.lastUpdate.getTime() < 60 * 60 * 1000) {
|
|
return this.cache;
|
|
}
|
|
return await this.refreshData().then(() => {
|
|
return this.cache;
|
|
});
|
|
}
|
|
|
|
private async refreshData(): Promise<Github> {
|
|
const response
|
|
= await fetch("https://api.github.com/users/naomi-lgbt/events");
|
|
// eslint-disable-next-line @typescript-eslint/consistent-type-assertions
|
|
const data = await response.json() as Array<ActivityData>;
|
|
this.cache = data;
|
|
this.lastUpdate = new Date();
|
|
return this;
|
|
}
|
|
}
|
|
|
|
const instantiated = new Github();
|
|
|
|
/**
|
|
* Fetches and caches the Github activity.
|
|
* @returns An array of activity objects.
|
|
*/
|
|
export const getGithubData = async(): Promise<Array<ActivityData>> => {
|
|
return await instantiated.getActivities();
|
|
};
|