Skip to content

Commit

Permalink
feat(hcb): add new HCB badges for @hackclub
Browse files Browse the repository at this point in the history
Updated docs soon, but we'll wrapping up Arcade work here for now.

Context: andreijiroh-dev/personal-launchpad#4
On-behalf-of: @andreijiroh-dev <ajhalili2006@andreijiroh.xyz>

Signed-off-by: Andrei Jiroh Halili (RecapTime.dev) <ajhalili2006@crew.recaptime.dev>
  • Loading branch information
ajhalili2006 committed Sep 1, 2024
1 parent 2104113 commit c8265d6
Show file tree
Hide file tree
Showing 3 changed files with 134 additions and 22 deletions.
106 changes: 105 additions & 1 deletion api/badges.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,16 +4,120 @@ import { z } from "zod";
import { BadgeData, getBadgeData, resolveBadgeIcon } from "../lib/db.ts";
import { Format, makeBadge } from "badge-maker";
import { makeLogo } from "../lib/logos.ts";
import { getOrgData } from "../lib/hcb.ts";

export class hcbBalanceOps extends OpenAPIRoute {
schema = {
tags: ["badges"],
tags: ["hcb"],
summary: "Generate a SVG badge of a HCB organization's balances",
descritpion: `\
By default without the \`org\` query parameter, it will uses data from [Hack Club HQ](https://hcb.hackclub.com/api/v3/organizations/hq),
but it will change to either \`recaptime-dev\` or \`lorebooks-wiki\` in the future.
`,
request: {
query: z.object({
org: Str({
description: "Organization slug or ID",
required: false,
default: "hq",
}),
style: Str({
description: "Badge style as supported by `badge-maker` npm library.",
required: false,
default: "flat",
}),
}),
},
responses: {
"200": {
content: {
"image/svg+xml": {
schema: {
type: "string",
},
},
},
},
},
};

async handle(c: Context) {
const apiReqData = await this.getValidatedData<typeof this.schema>();
const { org, style } = apiReqData.query;
const { result, code } = await getOrgData(org || "hq");
console.log(`API result: ${JSON.stringify(result)} | code is ${code}`);

if (code == 200) {
const bal = result.balances.balance_cents / 100;
const badge: Format = {
label: `HCB balance for ${org}`,
labelColor: "EC3750",
message: `USD ${bal}`,
logoBase64: await resolveBadgeIcon("hcb-dark"),
style: style || "flat",
};
const badgeSvg = makeBadge(badge);
return c.newResponse(badgeSvg, 200, {
"Content-Type": "image/svg+xml",
});
}
}
}

export class hcbDonateButton extends OpenAPIRoute {
schema = {
tags: ["hcb"],
summary: "Generate a SVG badge of a HCB organization's balances",
descritpion: `\
By default without the \`org\` query parameter, it will uses data from [Hack Club HQ](https://hcb.hackclub.com/api/v3/organizations/hq),
but it will change to either \`recaptime-dev\` or \`lorebooks-wiki\` in the future.
`,
request: {
query: z.object({
org: Str({
description: "Organization slug or ID",
required: false,
default: "hq",
}),
style: Str({
description: "Badge style as supported by `badge-maker` npm library.",
required: false,
default: "flat",
}),
}),
},
responses: {
"200": {
content: {
"image/svg+xml": {
schema: {
type: "string",
},
},
},
},
},
};

async handle(c: Context) {
const apiReqData = await this.getValidatedData<typeof this.schema>();
const { org, style } = apiReqData.query;
const dbData = (await getBadgeData("hcb", "donate")).result?.data;
const badgeData: Format = {
label: dbData?.label,
labelColor: dbData?.labelColor,
logoBase64: await resolveBadgeIcon("hcb-dark"),
message: `Donate to ${org || "HQ"}`,
links: [
`https://hcb.hackclub.com/donations/start/${org || "hq"}`,
`https://hcb.hackclub.com/donations/start/${org || "hq"}`,
],
};
const badge = makeBadge(badgeData);
return c.newResponse(badge, 200, {
"Content-Type": "image/svg+xml",
});
}
}

export class generateSvg extends OpenAPIRoute {
Expand Down
25 changes: 15 additions & 10 deletions lib/metadata.ts
Original file line number Diff line number Diff line change
@@ -1,16 +1,21 @@
import { config } from "./config.ts";

export const tags = [
{
name: "badges",
description: "The Badges API endpoint itself"
}
]
{
name: "badges",
description: "The Badges API endpoint itself",
},
{
name: "hcb",
description:
"HCB badges for use by organizations and communties fiscally sponsored by Hack Club through HCB",
},
];

export const contact = {
name: "Recap Time Squad",
url: "https://github.com/lorebooks-wiki/badges-api/issues"
}
name: "Recap Time Squad",
url: "https://github.com/lorebooks-wiki/badges-api/issues",
};

export const servers = [
{
Expand All @@ -19,7 +24,7 @@ export const servers = [
},
{
url: "https://lorebooks-badges-api.deno.dev",
description: "Production (deno.dev alt domain)"
description: "Production (deno.dev alt domain)",
},
{
url: `http://localhost:${config.port}`,
Expand All @@ -33,4 +38,4 @@ export const description = `\
If you want to add a new logo or even a static badge for you or your project without the long \`img.shields.io\` URLs, please file a issue through the \
contact link below.
`
`;
25 changes: 14 additions & 11 deletions main.ts
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
import { Hono } from "hono"
import { Hono } from "hono";
import { cors } from "hono/cors";
import {fromHono} from "chanfana"
import { fromHono } from "chanfana";
import { makeBadge, ValidationError } from "badge-maker";
import { config } from "./lib/config.ts";
import { servers, tags, description, contact } from "./lib/metadata.ts";
import { generateSvg } from "./api/badges.ts";
import { generateSvg, hcbBalanceOps, hcbDonateButton } from "./api/badges.ts";
import { ping } from "./api/meta.ts";

const app = new Hono()
const app = new Hono();
app.use(cors());
const openapi = fromHono(app, {
schema: {
Expand All @@ -27,16 +27,19 @@ const openapi = fromHono(app, {
tags,
externalDocs: {
url: "https://github.com/lorebooks-wiki/badges-api/tree/main/docs",
description: "More docuemntation available in GitHub repository"
description: "More docuemntation available in GitHub repository",
},
},
docs_url: "/docs",
});
openapi.get("/badges/:project/:badgeName", generateSvg)
openapi.get("/ping", ping)

app.get('/', (c) => {
return c.redirect(config.homepage)
})
openapi.get("/hcb/balance", hcbBalanceOps);
openapi.get("/hcb/donate", hcbDonateButton);
openapi.get("/badges/:project/:badgeName", generateSvg);
openapi.get("/ping", ping);

Deno.serve({ port: config.port }, app.fetch)
app.get("/", (c) => {
return c.redirect(config.homepage);
});

Deno.serve({ port: config.port }, app.fetch);

0 comments on commit c8265d6

Please sign in to comment.