-
-
Notifications
You must be signed in to change notification settings - Fork 3
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
* chore(types): add type definitions for stratagem feature * feat: add stratagem database entities * lib(assets): add stratagem json file * fix: properly define activation and cooldown properties * feat: add routes and controllers for stratagems * feat: implement stratagem generation * refractor: arrange static assets by type * lib(assets): add stratagem assets * lib(middleware): add custom middleware for static file serving * feat: implement file serving middleware * refractor: add base url for stratagem file serving
- Loading branch information
1 parent
c5d45bb
commit b0536d1
Showing
71 changed files
with
2,202 additions
and
19 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,23 @@ | ||
-- CreateTable | ||
CREATE TABLE "StratagemGroup" ( | ||
"id" INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT, | ||
"name" TEXT NOT NULL, | ||
"createdAt" DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP, | ||
"updatedAt" DATETIME NOT NULL | ||
); | ||
|
||
-- CreateTable | ||
CREATE TABLE "Stratagem" ( | ||
"id" INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT, | ||
"codename" TEXT, | ||
"name" TEXT NOT NULL, | ||
"keys" TEXT NOT NULL, | ||
"uses" TEXT NOT NULL, | ||
"cooldown" INTEGER, | ||
"activation" INTEGER, | ||
"imageUrl" TEXT NOT NULL, | ||
"groupId" INTEGER, | ||
"createdAt" DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP, | ||
"updatedAt" DATETIME NOT NULL, | ||
CONSTRAINT "Stratagem_groupId_fkey" FOREIGN KEY ("groupId") REFERENCES "StratagemGroup" ("id") ON DELETE SET NULL ON UPDATE CASCADE | ||
); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,83 @@ | ||
import type { Context } from "hono"; | ||
import { PrismaClient } from "@prisma/client"; | ||
|
||
import witCache from "utils/cache"; | ||
import parseIntParam from "utils/params"; | ||
import parseQueryParams from "utils/query"; | ||
|
||
const prisma = new PrismaClient(); | ||
|
||
export const getStratagemById = await witCache(async (ctx: Context) => { | ||
try { | ||
const id = parseIntParam(ctx, "id"); | ||
const query = await parseQueryParams(ctx); | ||
|
||
delete query.orderBy; | ||
delete query.where; | ||
delete query.orderBy; | ||
delete (query as any).skip; | ||
delete (query as any).take; | ||
|
||
const stratagem = await prisma.stratagem.findUnique({ | ||
...(query as any), | ||
where: { id }, | ||
}); | ||
|
||
if (!stratagem) { | ||
ctx.status(404); | ||
return ctx.json({ | ||
data: null, | ||
error: { details: [`Stratagem with id (${id}) not found`] }, | ||
}); | ||
} | ||
|
||
// slightly transform the data | ||
const imageBaseUrl = process.env.STRATAGEM_IMAGE_URL || ""; | ||
stratagem.imageUrl = `${imageBaseUrl}${stratagem.imageUrl}`; | ||
(stratagem as any).keys = stratagem.keys.split(","); | ||
|
||
return ctx.json({ data: stratagem, error: null }); | ||
} catch (error: any) { | ||
console.error(error); | ||
ctx.status(500); | ||
return ctx.json({ | ||
data: null, | ||
error: { details: [error.message] }, | ||
}); | ||
} | ||
}); | ||
|
||
export const getAllStratagems = await witCache(async (ctx: Context) => { | ||
try { | ||
const query = await parseQueryParams(ctx); | ||
|
||
const [count, stratagems] = await Promise.all([ | ||
prisma.stratagem.count({ where: query.where }), | ||
prisma.stratagem.findMany(query), | ||
]); | ||
|
||
return ctx.json({ | ||
data: stratagems.map(stratagem => { | ||
// slightly transform the data | ||
const imageBaseUrl = process.env.STRATAGEM_IMAGE_URL || ""; | ||
stratagem.imageUrl = `${imageBaseUrl}${stratagem.imageUrl}`; | ||
(stratagem as any).keys = stratagem.keys.split(","); | ||
return stratagem; | ||
}), | ||
error: null, | ||
pagination: { | ||
page: query.skip / query.take + 1, | ||
pageSize: query.take, | ||
pageCount: Math.ceil((count as number) / query.take), | ||
total: count, | ||
}, | ||
}); | ||
} catch (error: any) { | ||
console.error(error); | ||
ctx.status(500); | ||
return ctx.json({ | ||
data: null, | ||
error: { details: [error.message] }, | ||
}); | ||
} | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,97 @@ | ||
import path from "path"; | ||
import type { Context, Next } from "hono"; | ||
|
||
const getMimeType = (filename: string) => { | ||
const mimes = { | ||
aac: "audio/aac", | ||
avi: "video/x-msvideo", | ||
avif: "image/avif", | ||
av1: "video/av1", | ||
bin: "application/octet-stream", | ||
bmp: "image/bmp", | ||
css: "text/css", | ||
csv: "text/csv", | ||
eot: "application/vnd.ms-fontobject", | ||
epub: "application/epub+zip", | ||
gif: "image/gif", | ||
gz: "application/gzip", | ||
htm: "text/html", | ||
html: "text/html", | ||
ico: "image/x-icon", | ||
ics: "text/calendar", | ||
jpeg: "image/jpeg", | ||
jpg: "image/jpeg", | ||
js: "text/javascript", | ||
json: "application/json", | ||
jsonld: "application/ld+json", | ||
map: "application/json", | ||
mid: "audio/x-midi", | ||
midi: "audio/x-midi", | ||
mjs: "text/javascript", | ||
mp3: "audio/mpeg", | ||
mp4: "video/mp4", | ||
mpeg: "video/mpeg", | ||
oga: "audio/ogg", | ||
ogv: "video/ogg", | ||
ogx: "application/ogg", | ||
opus: "audio/opus", | ||
otf: "font/otf", | ||
pdf: "application/pdf", | ||
png: "image/png", | ||
rtf: "application/rtf", | ||
svg: "image/svg+xml", | ||
tif: "image/tiff", | ||
tiff: "image/tiff", | ||
ts: "video/mp2t", | ||
ttf: "font/ttf", | ||
txt: "text/plain", | ||
wasm: "application/wasm", | ||
webm: "video/webm", | ||
weba: "audio/webm", | ||
webp: "image/webp", | ||
woff: "font/woff", | ||
woff2: "font/woff2", | ||
xhtml: "application/xhtml+xml", | ||
xml: "application/xml", | ||
zip: "application/zip", | ||
"3gp": "video/3gpp", | ||
"3g2": "video/3gpp2", | ||
gltf: "model/gltf+json", | ||
glb: "model/gltf-binary", | ||
}; | ||
|
||
const regexp = /\.([a-zA-Z0-9]+?)$/; | ||
const match = filename.match(regexp); | ||
if (!match) return; | ||
let mimeType = mimes[match[1] as keyof typeof mimes]; | ||
if ( | ||
(mimeType && mimeType.startsWith("text")) || | ||
mimeType === "application/json" | ||
) { | ||
mimeType += "; charset=utf-8"; | ||
} | ||
return mimeType; | ||
}; | ||
|
||
export default async function files(ctx: Context, next: Next) { | ||
try { | ||
const _ctx = { | ||
...ctx, | ||
req: { ...ctx.req, url: ctx.req.url.replace("/api", "") }, | ||
}; | ||
|
||
const { pathname } = new URL(_ctx.req.url); | ||
if (!pathname.startsWith("/static/")) await next(); | ||
|
||
const file = Bun.file(path.join(process.cwd(), "src", pathname)); | ||
if (!file) await next(); | ||
|
||
const mimeType = getMimeType(`..${pathname}`); | ||
if (!mimeType) return await next(); | ||
|
||
const content = await file.arrayBuffer(); | ||
return ctx.newResponse(content, 200, { "Content-Type": mimeType }); | ||
} catch { | ||
return ctx.newResponse("Not Found", 404); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
import type { Hono } from "hono"; | ||
|
||
import * as Stratagems from "controllers/stratagems"; | ||
|
||
export default async function stratagems(app: Hono) { | ||
app.get("/stratagems", Stratagems.getAllStratagems); | ||
app.get("/stratagems/:id", Stratagems.getStratagemById); | ||
} | ||
//https://api-helldivers-companion.koyeb.app |
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Oops, something went wrong.