This commit is contained in:
1 parent
8efd032cc6
commit
df38dccbf1
735 files changed
+128321
-120870
No files matched your search
+37
-26
@@ -8,47 +8,58 @@ import { NextResponse } from "next/server";
|
||||
const CORS_ORIGIN = process.env.APP_URL ?? "http://localhost:3000";
|
||||
|
||||
export function apiJson(data: unknown, init?: ResponseInit): NextResponse {
|
||||
const body = JSON.stringify(data, (_k, v) => (typeof v === "bigint" ? v.toString() : v));
|
||||
return new NextResponse(body, {
|
||||
status: init?.status ?? 200,
|
||||
headers: {
|
||||
"content-type": "application/json; charset=utf-8",
|
||||
"access-control-allow-origin": CORS_ORIGIN,
|
||||
"cache-control": "no-store",
|
||||
...(init?.headers ?? {}),
|
||||
},
|
||||
});
|
||||
const body = JSON.stringify(data, (_k, v) =>
|
||||
typeof v === "bigint" ? v.toString() : v,
|
||||
);
|
||||
return new NextResponse(body, {
|
||||
status: init?.status ?? 200,
|
||||
headers: {
|
||||
"content-type": "application/json; charset=utf-8",
|
||||
"access-control-allow-origin": CORS_ORIGIN,
|
||||
"cache-control": "no-store",
|
||||
...(init?.headers ?? {}),
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
/** Standard error envelope. */
|
||||
export function apiError(message: string, status = 400): NextResponse {
|
||||
return apiJson({ error: message }, { status });
|
||||
return apiJson({ error: message }, { status });
|
||||
}
|
||||
|
||||
/** Safe response for temporary infrastructure failures. */
|
||||
export function apiUnavailable(message = "Service temporarily unavailable"): NextResponse {
|
||||
return apiError(message, 503);
|
||||
export function apiUnavailable(
|
||||
message = "Service temporarily unavailable",
|
||||
): NextResponse {
|
||||
return apiError(message, 503);
|
||||
}
|
||||
|
||||
/** Parse an unsigned, non-zero database identifier without Number precision loss. */
|
||||
export function positiveBigInt(raw: string | null): bigint | null {
|
||||
if (!raw || !/^\d+$/.test(raw)) return null;
|
||||
const value = BigInt(raw);
|
||||
return value > 0n ? value : null;
|
||||
if (!raw || !/^\d+$/.test(raw)) return null;
|
||||
const value = BigInt(raw);
|
||||
return value > 0n ? value : null;
|
||||
}
|
||||
|
||||
/** Clamp a ?page / ?perPage pair from search params. */
|
||||
export function pagination(searchParams: URLSearchParams, defaultPer = 20, maxPer = 100) {
|
||||
const requestedPage = positiveInteger(searchParams.get("page"), 1);
|
||||
const requestedPerPage = positiveInteger(searchParams.get("perPage"), defaultPer);
|
||||
const perPage = Math.min(maxPer, requestedPerPage);
|
||||
const maxSafePage = Math.floor(Number.MAX_SAFE_INTEGER / perPage) + 1;
|
||||
const page = Math.min(requestedPage, maxSafePage);
|
||||
return { page, perPage, skip: (page - 1) * perPage, take: perPage };
|
||||
export function pagination(
|
||||
searchParams: URLSearchParams,
|
||||
defaultPer = 20,
|
||||
maxPer = 100,
|
||||
) {
|
||||
const requestedPage = positiveInteger(searchParams.get("page"), 1);
|
||||
const requestedPerPage = positiveInteger(
|
||||
searchParams.get("perPage"),
|
||||
defaultPer,
|
||||
);
|
||||
const perPage = Math.min(maxPer, requestedPerPage);
|
||||
const maxSafePage = Math.floor(Number.MAX_SAFE_INTEGER / perPage) + 1;
|
||||
const page = Math.min(requestedPage, maxSafePage);
|
||||
return { page, perPage, skip: (page - 1) * perPage, take: perPage };
|
||||
}
|
||||
|
||||
function positiveInteger(raw: string | null, fallback: number): number {
|
||||
if (!raw || !/^\d+$/.test(raw)) return fallback;
|
||||
const value = Number(raw);
|
||||
return Number.isSafeInteger(value) && value > 0 ? value : fallback;
|
||||
if (!raw || !/^\d+$/.test(raw)) return fallback;
|
||||
const value = Number(raw);
|
||||
return Number.isSafeInteger(value) && value > 0 ? value : fallback;
|
||||
}
|
||||
Reference in new issue
Block a user