Merge branch 'fix/biome-lint-debt' into chore/consolidate-v2.0.0

This commit is contained in:
SnapOtter
2026-06-21 02:31:28 +08:00
23 changed files with 36 additions and 45 deletions
+10 -10
View File
@@ -74,7 +74,7 @@ async function getS3(): Promise<S3StorageModule> {
return s3Mod;
}
function useS3(): boolean {
function isS3Enabled(): boolean {
return env.STORAGE_MODE === "s3";
}
@@ -92,7 +92,7 @@ let storageReady = false;
export async function ensureStorageDir(): Promise<void> {
if (storageReady) return;
if (useS3()) {
if (isS3Enabled()) {
const s3 = await getS3();
await s3.checkConnection();
storageReady = true;
@@ -115,7 +115,7 @@ export async function ensureStorageDir(): Promise<void> {
export async function saveFile(buffer: Buffer, originalName: string): Promise<string> {
const storedName = generateStoredName(originalName);
if (useS3()) {
if (isS3Enabled()) {
const s3 = await getS3();
await s3.putObject(storedName, buffer);
return storedName;
@@ -138,7 +138,7 @@ export async function saveFile(buffer: Buffer, originalName: string): Promise<st
}
export async function readStoredFile(storedName: string): Promise<Buffer> {
if (useS3()) {
if (isS3Enabled()) {
const s3 = await getS3();
return s3.getObject(storedName);
}
@@ -146,7 +146,7 @@ export async function readStoredFile(storedName: string): Promise<Buffer> {
}
export async function streamStoredFile(storedName: string): Promise<Readable> {
if (useS3()) {
if (isS3Enabled()) {
const s3 = await getS3();
return s3.getObjectStream(storedName);
}
@@ -154,7 +154,7 @@ export async function streamStoredFile(storedName: string): Promise<Readable> {
}
export async function deleteStoredFile(storedName: string): Promise<void> {
if (useS3()) {
if (isS3Enabled()) {
const s3 = await getS3();
await s3.deleteObject(storedName);
return;
@@ -177,7 +177,7 @@ let thumbDirReady = false;
async function ensureThumbDir(): Promise<void> {
if (thumbDirReady) return;
if (useS3()) {
if (isS3Enabled()) {
thumbDirReady = true;
return;
}
@@ -197,7 +197,7 @@ function thumbPath(storedName: string): string {
}
export async function getCachedThumbnail(storedName: string): Promise<Buffer | null> {
if (useS3()) {
if (isS3Enabled()) {
const s3 = await getS3();
return s3.getThumbnail(storedName);
}
@@ -209,7 +209,7 @@ export async function getCachedThumbnail(storedName: string): Promise<Buffer | n
}
export async function saveThumbnail(storedName: string, buffer: Buffer): Promise<void> {
if (useS3()) {
if (isS3Enabled()) {
const s3 = await getS3();
await s3.putThumbnail(storedName, buffer);
return;
@@ -219,7 +219,7 @@ export async function saveThumbnail(storedName: string, buffer: Buffer): Promise
}
export async function deleteThumbnail(storedName: string): Promise<void> {
if (useS3()) {
if (isS3Enabled()) {
const s3 = await getS3();
await s3.deleteThumbnail(storedName);
return;
+9 -9
View File
@@ -37,7 +37,7 @@ function localPath(key: string): string {
return p;
}
function useS3(): boolean {
function isS3Enabled(): boolean {
return env.STORAGE_MODE === "s3";
}
@@ -102,7 +102,7 @@ export async function assertLocalCapacity(): Promise<void> {
export async function putObject(key: string, data: Buffer): Promise<void> {
assertValidKey(key);
if (useS3()) {
if (isS3Enabled()) {
const s3 = await getS3();
await s3.putGenericObject(key, data);
return;
@@ -129,7 +129,7 @@ export async function putObjectStream(
yield chunk;
}
};
if (useS3()) {
if (isS3Enabled()) {
const s3 = await getS3();
await s3.putGenericObjectStream(key, counter(source));
return written;
@@ -151,7 +151,7 @@ export async function getObjectStream(
range?: { start: number; end?: number },
): Promise<Readable> {
assertValidKey(key);
if (useS3()) {
if (isS3Enabled()) {
const s3 = await getS3();
return s3.getGenericObjectStream(key, range);
}
@@ -166,7 +166,7 @@ export async function getObjectBuffer(key: string): Promise<Buffer> {
export async function getObjectSize(key: string): Promise<number> {
assertValidKey(key);
if (useS3()) {
if (isS3Enabled()) {
const s3 = await getS3();
return s3.getGenericObjectSize(key);
}
@@ -184,7 +184,7 @@ export async function objectExists(key: string): Promise<boolean> {
export async function deleteObject(key: string): Promise<void> {
assertValidKey(key);
if (useS3()) {
if (isS3Enabled()) {
const s3 = await getS3();
await s3.deleteGenericObject(key);
return;
@@ -196,7 +196,7 @@ export async function deletePrefix(prefix: string): Promise<void> {
if (!/^(uploads|outputs)\/[A-Za-z0-9][A-Za-z0-9._-]*\/?$/.test(prefix)) {
throw new Error(`Invalid prefix: ${prefix}`);
}
if (useS3()) {
if (isS3Enabled()) {
const s3 = await getS3();
await s3.deleteGenericPrefix(prefix);
return;
@@ -208,7 +208,7 @@ export async function listObjects(prefix: string): Promise<ObjectInfo[]> {
if (!/^(uploads|outputs)\/[A-Za-z0-9][A-Za-z0-9._-]*\/?$/.test(prefix) || prefix.includes("..")) {
throw new Error(`Invalid prefix: ${prefix}`);
}
if (useS3()) {
if (isS3Enabled()) {
const s3 = await getS3();
return s3.listGenericObjects(prefix);
}
@@ -233,7 +233,7 @@ export async function listObjects(prefix: string): Promise<ObjectInfo[]> {
// Lists the top-level job directories under a prefix with their mtime so the
// TTL sweeper can expire whole jobs. S3 derives them from key listings.
export async function listJobDirs(prefix: "uploads" | "outputs"): Promise<ObjectInfo[]> {
if (useS3()) {
if (isS3Enabled()) {
const s3 = await getS3();
return s3.listGenericJobDirs(prefix);
}
+1 -1
View File
@@ -326,7 +326,7 @@ export async function authRoutes(app: FastifyInstance): Promise<void> {
const audit = auditFromRequest(request);
if (!user || !user.passwordHash) {
if (!user?.passwordHash) {
authAttempts.inc({ method: "password", result: "failure" });
await audit("LOGIN_FAILED", {
username: sanitizeAuditInput(body.username),
+1 -1
View File
@@ -108,7 +108,7 @@ export async function registerSaml(app: FastifyInstance): Promise<void> {
return redirectToLogin(reply, "saml_auth_failed");
}
if (!profile || !profile.nameID) {
if (!profile?.nameID) {
request.log.warn("SAML callback: no profile or nameID in assertion");
authAttempts.inc({ method: "saml", result: "failure" });
await audit("SAML_LOGIN_FAILED", { reason: "missing_profile" });
+2 -1
View File
@@ -463,7 +463,8 @@ export async function registerBatchRoutes(app: FastifyInstance): Promise<void> {
// Append results from object storage in original upload order
try {
for (const entry of successEntries) {
const stream = await getObjectStream(entry.outputRef!);
if (!entry.outputRef) continue;
const stream = await getObjectStream(entry.outputRef);
archive.append(stream, { name: entry.filename });
}
+1 -1
View File
@@ -4,7 +4,7 @@ import { z } from "zod";
import { env } from "../../config.js";
import { db, schema } from "../../db/index.js";
import { auditFromRequest } from "../../lib/audit.js";
import { encrypt, isEncrypted } from "../../lib/encryption.js";
import { encrypt } from "../../lib/encryption.js";
import { requirePermission } from "../../permissions.js";
const configSchema = z.object({
+2 -1
View File
@@ -1161,7 +1161,8 @@ export async function registerPipelineRoutes(app: FastifyInstance): Promise<void
// Append results from object storage in original upload order
try {
for (const entry of successEntries) {
const stream = await getObjectStream(entry.outputRef!);
if (!entry.outputRef) continue;
const stream = await getObjectStream(entry.outputRef);
archive.append(stream, { name: entry.filename });
}
+1 -1
View File
@@ -387,7 +387,7 @@ export async function registerProgressRoutes(app: FastifyInstance): Promise<void
if (!sseListeners.has(jobId)) {
sseListeners.set(jobId, new Set());
}
sseListeners.get(jobId)!.add(callback);
sseListeners.get(jobId)?.add(callback);
// Clean up on client disconnect
request.raw.on("close", () => {
+2 -1
View File
@@ -88,9 +88,10 @@ export function registerHtmlToImage(app: FastifyInstance) {
isMobile: preset.isMobile,
};
// Zod refine guarantees either url or html is present
const buffer = settings.html
? await captureHtml(settings.html, captureOpts)
: await capturePage(settings.url!, captureOpts);
: await capturePage(settings.url ?? "", captureOpts);
const jobId = randomUUID();
const ext = settings.format;