Skip to content

Commit

Permalink
Merge pull request #36 from tranzystorekk/codeberg-endpoints
Browse files Browse the repository at this point in the history
Add Codeberg endpoints
  • Loading branch information
SplittyDev authored Jan 14, 2024
2 parents eb90417 + 442be75 commit a186a1f
Show file tree
Hide file tree
Showing 7 changed files with 164 additions and 0 deletions.
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,7 @@ NEXT_PUBLIC_WEB_HOST = "127.0.0.1:3000" # Web frontend host
# API Tokens
GITHUB_TOKEN = "ghp_Foo1234567" # Required for GitHub badges
CRATESIO_TOKEN = "cio51fdR1234567" # Required for crates.io badges
CODEBERG_TOKEN = "foobar123456789" # Required for Codeberg badges
```

### spacebadgers
Expand Down
19 changes: 19 additions & 0 deletions badgers-web/src/app/codeberg/closed-issues/[owner]/[repo]/route.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
import { NextRequest } from "next/server"

import Badge from '@/utils/Badge'
import Codeberg from '@/utils/Codeberg'

interface Params {
params: {
owner: string
repo: string
}
}

export async function GET(request: NextRequest, { params: { owner, repo } }: Params) {
const closedIssuesCount = await Codeberg.getClient().getIssuesCount({ owner, repo }, { type: 'issues', state: 'closed' })

return await Badge.generate(request, 'closed issues', closedIssuesCount?.toString() ?? 'None')
}

export const runtime = 'edge'
19 changes: 19 additions & 0 deletions badgers-web/src/app/codeberg/issues/[owner]/[repo]/route.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
import { NextRequest } from "next/server"

import Badge from '@/utils/Badge'
import Codeberg from '@/utils/Codeberg'

interface Params {
params: {
owner: string
repo: string
}
}

export async function GET(request: NextRequest, { params: { owner, repo } }: Params) {
const issuesCount = await Codeberg.getClient().getIssuesCount({ owner, repo }, { type: 'issues', state: 'all' })

return await Badge.generate(request, 'issues', issuesCount?.toString() ?? 'None')
}

export const runtime = 'edge'
19 changes: 19 additions & 0 deletions badgers-web/src/app/codeberg/open-issues/[owner]/[repo]/route.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
import { NextRequest } from "next/server"

import Badge from '@/utils/Badge'
import Codeberg from '@/utils/Codeberg'

interface Params {
params: {
owner: string
repo: string
}
}

export async function GET(request: NextRequest, { params: { owner, repo } }: Params) {
const openIssuesCount = await Codeberg.getClient().getIssuesCount({ owner, repo }, { type: 'issues', state: 'open' })

return await Badge.generate(request, 'open issues', openIssuesCount?.toString() ?? 'None')
}

export const runtime = 'edge'
24 changes: 24 additions & 0 deletions badgers-web/src/app/codeberg/release/[owner]/[repo]/route.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
import { NextRequest } from 'next/server'

import Badge from '@/utils/Badge'
import Codeberg from '@/utils/Codeberg'

interface Params {
params: {
owner: string
repo: string
}
}

export async function GET(request: NextRequest, { params: { owner, repo } }: Params) {
const release = await Codeberg.getClient().getLatestRelease({ owner, repo })
const shortestName = [release?.tag_name, release?.name]
.filter(Boolean)
.reduce((a, b) => a!.length < b!.length ? a : b)

return await Badge.generate(request, 'release', shortestName ?? 'None', {
color: !!shortestName ? 'blue' : 'yellow'
})
}

export const runtime = 'edge'
8 changes: 8 additions & 0 deletions badgers-web/src/app/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -160,6 +160,14 @@ export default function Home() {
<Row name="License" path="/github/license/:owner/:repo" inject={['quintschaf', 'schafkit']} />
</div>
</Section>
<Section name="Codeberg">
<div className="grid grid-cols-[auto_1fr_auto] items-center gap-x-8">
<Row name="Latest release" path="/codeberg/release/:owner/:repo" inject={['forgejo', 'forgejo']} />
<Row name="Issues" path="/codeberg/issues/:owner/:repo" inject={['forgejo', 'forgejo']} />
<Row name="Open issues" path="/codeberg/open-issues/:owner/:repo" inject={['forgejo', 'forgejo']} />
<Row name="Closed issues" path="/codeberg/closed-issues/:owner/:repo" inject={['forgejo', 'forgejo']} />
</div>
</Section>
<Section name="crates.io">
<div className="grid grid-cols-[auto_1fr_auto] items-center gap-x-8">
<Row name="Name" path="/crates/name/:crate" inject={['serde']} />
Expand Down
74 changes: 74 additions & 0 deletions badgers-web/src/utils/Codeberg.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
const API_BASE = 'https://codeberg.org/api/v1';

type ProjectInfo = {
owner: string
repo: string
}

type Repository = {
id: number
default_branch: string
name: string
forks_count: number
stars_count: number
}

type Release = {
name: string
tag_name: string
}

class CodebergClient {
token: string

constructor(token: string) {
this.token = token
}

buildUrl(path: string, query: Record<string, any> = {}): string {
const queryArgs = {
...query,
token: this.token,
}
const queryString = Object
.entries(queryArgs)
.map(([key, value]) => `${key}=${encodeURIComponent(value)}`)
.join('&')

return `${API_BASE}/${path}?${queryString}`
}

async getRepository({ owner, repo }: ProjectInfo): Promise<Repository | null> {
const repoId = `${owner}/${repo}`
const url = this.buildUrl(`repos/${repoId}`)
const resp = await fetch(url)

if (resp.status !== 200) return null
return await resp.json() as Repository
}

async getIssuesCount({ owner, repo }: ProjectInfo, query: Record<string, any> = {}): Promise<Number | null> {
const repoId = `${owner}/${repo}`
const url = this.buildUrl(`repos/${repoId}/issues`, query)
const resp = await fetch(url)

if (resp.status !== 200) return null
const count = resp.headers.get('x-total-count')
return Number(count)
}

async getLatestRelease({ owner, repo }: ProjectInfo): Promise<Release | null> {
const repoId = `${owner}/${repo}`
const url = this.buildUrl(`repos/${repoId}/releases/latest`)
const resp = await fetch(url)

if (resp.status !== 200) return null
return await resp.json() as Release
}
}

export default class Codeberg {
static getClient(): CodebergClient {
return new CodebergClient(process.env.CODEBERG_TOKEN as string)
}
}

1 comment on commit a186a1f

@vercel
Copy link

@vercel vercel bot commented on a186a1f Jan 14, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please sign in to comment.