Skip to content

Instantly share code, notes, and snippets.

@statico
Created February 13, 2022 04:12
Embed
What would you like to do?
Next.js API route helpers
import { encode } from "html-entities"
import { getReasonPhrase, StatusCodes } from "http-status-codes"
import stringify from "json-stringify-safe"
import { NextApiResponse } from "next"
// Semantic sugar for returning various status codes, optionally with messages.
export const statusHelper = (res: NextApiResponse) => ({
codes: StatusCodes,
status(code: number, message?: string): void {
const phrase = getReasonPhrase(code)
const body = phrase + (message ? ` - ${message}` : "")
res.status(code).send(body)
},
// Extra helper to pretty-print JSON in development mode or if true is passed
// as the second param.
json(object: any, pretty?: boolean): void {
res.setHeader("Content-Type", "application/json; charset=utf-8")
if (pretty === undefined) pretty = __DEV__
const text = pretty ? stringify(object, null, 2) : stringify(object)
res.send(text)
},
// Make simple CGI-like pages using a zero-markup CSS library.
html(body = "", raw?: boolean): void {
const buildId = process.env.NEXT_PUBLIC_BUILD_ID
const baseUrl = process.env.NEXT_PUBLIC_BASE_URL
res.setHeader("Content-Type", "text/html; charset=utf-8")
if (raw) {
res.send(body)
} else {
res.send(`
<!doctype html>
<html>
<head>
<title>Admin</title>
<meta charset="utf-8"/>
<meta name="viewport" content="width=device-width, initial-scale=1"/>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/mini.css/3.0.1/mini-default.min.css"/>
<style type="text/css">
nav {
position: fixed;
margin: 0;
left: 0;
top: 0;
bottom: 0;
width: 200px;
background: #eee;
}
main { margin-left: 220px; }
nav * { line-height: 1; margin: 0; }
pre * { font-family: monospace; }
hr { padding: 0 }
input[type="text"] { min-width:400px; }
h6 { opacity: 0.5; overflow: hidden; text-overflo: ellipsis; }
</style>
</head>
<body>
<nav>
<a href="/"><img src="/favicon.ico" width="32"/></a>
<h5>Admin</h5>
<hr/>
<a href="/api/admin/me">Me</a>
<a href="/api/admin/users">Users</a>
<a href="/api/admin/communities">Communities</a>
<hr/>
<a href="/api/admin/test">Test</a>
<hr/>
<h6>
${baseUrl}<br/>
Build ID<br/>
${buildId}
</h6>
</nav>
<main>${body}</main>
</body>
</html>
`)
}
},
// Additional HTML helpers
stringify: (obj: any) => stringify(obj, null, 2),
escape: encode,
})
// The type of values in req.query is string | string[], but this isn't true
// since a value could be undefined. This guarantees what you expect from
// req.query in most cases: you get a string (which might be empty) or null.
export const singleParam = (value: any): string | null => {
if (value == null) {
return null
} else if (Array.isArray(value)) {
return String(value[0])
} else {
return String(value)
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment