fix: resolve biome lint errors in prisma-facade
- Fix noPrecisionLoss on BIGINT UNSIGNED max value (2^64-1) with biome-ignore comments - Fix noThenProperty on custom thenable with biome-ignore comment - Auto-format remaining files (biome check --write) - Re-stage auto-fixed files from previous commit
This commit is contained in:
1 parent
56061e41d4
commit
beae86194d
22 files changed
+151
-152
No files matched your search
+31
-25
@@ -1,47 +1,53 @@
|
||||
const fs = require('fs');
|
||||
const JSON5 = require('json5');
|
||||
const fs = require("fs");
|
||||
const JSON5 = require("json5");
|
||||
|
||||
const exampleFile = process.argv[2];
|
||||
const targetFile = process.argv[3];
|
||||
|
||||
if (!exampleFile || !targetFile) {
|
||||
process.exit(1);
|
||||
process.exit(1);
|
||||
}
|
||||
|
||||
function deepMerge(target, source) {
|
||||
const result = { ...target };
|
||||
for (const key of Object.keys(source)) {
|
||||
if (source[key] !== null && typeof source[key] === 'object' && !Array.isArray(source[key])) {
|
||||
result[key] = deepMerge(target[key] || {}, source[key]);
|
||||
} else {
|
||||
if (!(key in result)) {
|
||||
result[key] = source[key];
|
||||
}
|
||||
}
|
||||
}
|
||||
return result;
|
||||
const result = { ...target };
|
||||
for (const key of Object.keys(source)) {
|
||||
if (
|
||||
source[key] !== null &&
|
||||
typeof source[key] === "object" &&
|
||||
!Array.isArray(source[key])
|
||||
) {
|
||||
result[key] = deepMerge(target[key] || {}, source[key]);
|
||||
} else {
|
||||
if (!(key in result)) {
|
||||
result[key] = source[key];
|
||||
}
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
let example;
|
||||
try {
|
||||
const content = fs.readFileSync(exampleFile, 'utf-8');
|
||||
example = JSON5.parse(content);
|
||||
const content = fs.readFileSync(exampleFile, "utf-8");
|
||||
example = JSON5.parse(content);
|
||||
} catch {
|
||||
process.exit(1);
|
||||
process.exit(1);
|
||||
}
|
||||
|
||||
let current = {};
|
||||
try {
|
||||
if (fs.existsSync(targetFile)) {
|
||||
const content = fs.readFileSync(targetFile, 'utf-8');
|
||||
current = JSON5.parse(content);
|
||||
}
|
||||
if (fs.existsSync(targetFile)) {
|
||||
const content = fs.readFileSync(targetFile, "utf-8");
|
||||
current = JSON5.parse(content);
|
||||
}
|
||||
} catch {
|
||||
current = {};
|
||||
current = {};
|
||||
}
|
||||
|
||||
const merged = deepMerge(current, example);
|
||||
|
||||
const isJson5 = targetFile.endsWith('.json5');
|
||||
const output = isJson5 ? JSON5.stringify(merged, null, 4) : JSON.stringify(merged, null, 4);
|
||||
fs.writeFileSync(targetFile, output + '\n');
|
||||
const isJson5 = targetFile.endsWith(".json5");
|
||||
const output = isJson5
|
||||
? JSON5.stringify(merged, null, 4)
|
||||
: JSON.stringify(merged, null, 4);
|
||||
fs.writeFileSync(targetFile, output + "\n");
|
||||
+19
-21
@@ -88,29 +88,27 @@ export async function buyBadge(formData: FormData): Promise<void> {
|
||||
// Atomically deduct credits and persist the badge so a failure
|
||||
// between the two operations cannot orphan the user.
|
||||
if (price > 0) {
|
||||
await prisma.$transaction(
|
||||
async (tx) => {
|
||||
await tx.user.update({
|
||||
where: { id: userId },
|
||||
data: { credits: { decrement: price } },
|
||||
});
|
||||
await prisma.$transaction(async (tx) => {
|
||||
await tx.user.update({
|
||||
where: { id: userId },
|
||||
data: { credits: { decrement: price } },
|
||||
});
|
||||
|
||||
const existing = await tx.usersBadges.findFirst({
|
||||
where: { userId, badgeCode: code },
|
||||
select: { id: true },
|
||||
const existing = await tx.usersBadges.findFirst({
|
||||
where: { userId, badgeCode: code },
|
||||
select: { id: true },
|
||||
});
|
||||
if (!existing) {
|
||||
const max = await tx.usersBadges.aggregate({
|
||||
where: { userId },
|
||||
_max: { slotId: true },
|
||||
});
|
||||
if (!existing) {
|
||||
const max = await tx.usersBadges.aggregate({
|
||||
where: { userId },
|
||||
_max: { slotId: true },
|
||||
});
|
||||
const slotId = (max._max.slotId ?? 0) + 1;
|
||||
await tx.usersBadges.create({
|
||||
data: { userId, slotId, badgeCode: code },
|
||||
});
|
||||
}
|
||||
},
|
||||
);
|
||||
const slotId = (max._max.slotId ?? 0) + 1;
|
||||
await tx.usersBadges.create({
|
||||
data: { userId, slotId, badgeCode: code },
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// Grant the badge live so it appears immediately for online users.
|
||||
|
||||
@@ -85,9 +85,9 @@ export const createUser = adminAction(
|
||||
"code" in err &&
|
||||
err.code === "P2002"
|
||||
) {
|
||||
const target = (
|
||||
(err as { meta?: { target?: string[] } }).meta?.target as string[]
|
||||
) ?? [];
|
||||
const target =
|
||||
((err as { meta?: { target?: string[] } }).meta
|
||||
?.target as string[]) ?? [];
|
||||
if (target.includes("username"))
|
||||
throw new ActionError("Username already taken");
|
||||
if (target.includes("mail"))
|
||||
|
||||
@@ -3,10 +3,9 @@ import { redirect } from "next/navigation";
|
||||
import { getTranslations } from "next-intl/server";
|
||||
import { AdminPageShell } from "@/components/admin/admin-page-shell";
|
||||
import { CatalogTree } from "@/components/admin/catalog-tree";
|
||||
import { Prisma } from "@/lib/prisma";
|
||||
import { calcPagination, parseListParams } from "@/lib/admin-helpers";
|
||||
import { canAccess, getAdminContext, PERMS } from "@/lib/permissions";
|
||||
import { prisma } from "@/lib/prisma";
|
||||
import { Prisma, prisma } from "@/lib/prisma";
|
||||
import { getCatalogItemCounts } from "@/lib/services/catalog-tree";
|
||||
import { CatalogActions } from "./catalog-actions";
|
||||
import { CatalogManagerDialog } from "./catalog-manager-dialog-wrapper";
|
||||
|
||||
@@ -62,10 +62,7 @@ export default async function AdminHelpTicketsPage({
|
||||
? conditions[0]
|
||||
: { AND: conditions };
|
||||
|
||||
const SORT_MAP: Record<
|
||||
string,
|
||||
any
|
||||
> = {
|
||||
const SORT_MAP: Record<string, any> = {
|
||||
title: { title: "asc" },
|
||||
open: { open: "desc" },
|
||||
user: { userId: "asc" },
|
||||
|
||||
@@ -65,10 +65,7 @@ export default async function CfhListPage({
|
||||
? conditions[0]
|
||||
: { AND: conditions };
|
||||
|
||||
const SORT_MAP: Record<
|
||||
string,
|
||||
any
|
||||
> = {
|
||||
const SORT_MAP: Record<string, any> = {
|
||||
id: { id: "desc" },
|
||||
issue: { issue: "asc" },
|
||||
sender: { senderId: "asc" },
|
||||
|
||||
@@ -53,15 +53,14 @@ export default async function AdminTicketsPage({
|
||||
? conditions[0]
|
||||
: { AND: conditions };
|
||||
|
||||
const SORT_MAP: Record<string, any> =
|
||||
{
|
||||
subject: { subject: "asc" },
|
||||
status: { status: "asc" },
|
||||
priority: { priority: "asc" },
|
||||
assignee: { assigneeId: "asc" },
|
||||
date: { createdAt: "desc" },
|
||||
id: { id: "desc" },
|
||||
};
|
||||
const SORT_MAP: Record<string, any> = {
|
||||
subject: { subject: "asc" },
|
||||
status: { status: "asc" },
|
||||
priority: { priority: "asc" },
|
||||
assignee: { assigneeId: "asc" },
|
||||
date: { createdAt: "desc" },
|
||||
id: { id: "desc" },
|
||||
};
|
||||
|
||||
const baseOrder = SORT_MAP[parsed.sort ?? "date"] ?? { createdAt: "desc" };
|
||||
const orderField = Object.keys(baseOrder)[0] as keyof typeof baseOrder;
|
||||
|
||||
@@ -33,10 +33,7 @@ function formatAmount(amount: number, currency: string): string {
|
||||
return `${value} ${currency}`;
|
||||
}
|
||||
|
||||
const SORT_MAP: Record<
|
||||
string,
|
||||
any
|
||||
> = {
|
||||
const SORT_MAP: Record<string, any> = {
|
||||
id: { id: "desc" },
|
||||
amount: { amount: "desc" },
|
||||
date: { createdAt: "desc" },
|
||||
|
||||
@@ -29,10 +29,9 @@ export default async function EmulatorTranslationsPage({
|
||||
const perPage = Math.min(Math.max(parseInt(sp.perPage || "50", 10), 10), 200);
|
||||
const page = Math.max(parseInt(sp.page || "1", 10), 1);
|
||||
|
||||
const patternFilters: any[] =
|
||||
TRANSLATION_KEY_PATTERNS.map((p) => ({
|
||||
key: { contains: p.replace(/%/g, "") },
|
||||
}));
|
||||
const patternFilters: any[] = TRANSLATION_KEY_PATTERNS.map((p) => ({
|
||||
key: { contains: p.replace(/%/g, "") },
|
||||
}));
|
||||
|
||||
const baseFilter: any = { OR: patternFilters };
|
||||
|
||||
|
||||
@@ -1,8 +1,7 @@
|
||||
import { redirect } from "next/navigation";
|
||||
import { Tabs, TabsContent, TabsList, TabsTrigger } from "@/components/ui/tabs";
|
||||
import { Prisma } from "@/lib/prisma";
|
||||
import { canAccess, getAdminContext, PERMS } from "@/lib/permissions";
|
||||
import { prisma } from "@/lib/prisma";
|
||||
import { Prisma, prisma } from "@/lib/prisma";
|
||||
import { getWatchedUserIds } from "@/lib/services/watch";
|
||||
import { UserAccountInfo } from "../../_components/user-account-info";
|
||||
import { UserHero } from "../../_components/user-hero";
|
||||
|
||||
@@ -1,8 +1,7 @@
|
||||
import { Prisma } from "@/lib/prisma";
|
||||
import { withAdmin } from "@/lib/api-handler";
|
||||
import { apiError, apiOk } from "@/lib/api-response";
|
||||
import { PERMS } from "@/lib/permissions";
|
||||
import { prisma } from "@/lib/prisma";
|
||||
import { Prisma, prisma } from "@/lib/prisma";
|
||||
|
||||
interface UserPrefix {
|
||||
id: number;
|
||||
|
||||
@@ -1,9 +1,8 @@
|
||||
import { Prisma } from "@/lib/prisma";
|
||||
import { apiJson } from "@/lib/api";
|
||||
import { bearerUserId } from "@/lib/api-auth";
|
||||
import { auth } from "@/lib/auth";
|
||||
import { logger } from "@/lib/logger";
|
||||
import { prisma } from "@/lib/prisma";
|
||||
import { Prisma, prisma } from "@/lib/prisma";
|
||||
|
||||
export const dynamic = "force-dynamic";
|
||||
|
||||
|
||||
@@ -61,10 +61,7 @@ export default async function ModCfhListPage({
|
||||
? conditions[0]
|
||||
: { AND: conditions };
|
||||
|
||||
const SORT_MAP: Record<
|
||||
string,
|
||||
any
|
||||
> = {
|
||||
const SORT_MAP: Record<string, any> = {
|
||||
id: { id: "desc" },
|
||||
issue: { issue: "asc" },
|
||||
sender: { senderId: "asc" },
|
||||
|
||||
@@ -62,10 +62,7 @@ export default async function ModHelpTicketsPage({
|
||||
? conditions[0]
|
||||
: { AND: conditions };
|
||||
|
||||
const SORT_MAP: Record<
|
||||
string,
|
||||
any
|
||||
> = {
|
||||
const SORT_MAP: Record<string, any> = {
|
||||
title: { title: "asc" },
|
||||
open: { open: "desc" },
|
||||
user: { userId: "asc" },
|
||||
|
||||
@@ -53,15 +53,14 @@ export default async function ModTicketsPage({
|
||||
? conditions[0]
|
||||
: { AND: conditions };
|
||||
|
||||
const SORT_MAP: Record<string, any> =
|
||||
{
|
||||
subject: { subject: "asc" },
|
||||
status: { status: "asc" },
|
||||
priority: { priority: "asc" },
|
||||
assignee: { assigneeId: "asc" },
|
||||
date: { createdAt: "desc" },
|
||||
id: { id: "desc" },
|
||||
};
|
||||
const SORT_MAP: Record<string, any> = {
|
||||
subject: { subject: "asc" },
|
||||
status: { status: "asc" },
|
||||
priority: { priority: "asc" },
|
||||
assignee: { assigneeId: "asc" },
|
||||
date: { createdAt: "desc" },
|
||||
id: { id: "desc" },
|
||||
};
|
||||
|
||||
const baseOrder = SORT_MAP[parsed.sort ?? "date"] ?? { createdAt: "desc" };
|
||||
const orderField = Object.keys(baseOrder)[0] as keyof typeof baseOrder;
|
||||
|
||||
+57
-39
@@ -25,19 +25,22 @@ export const userRelations = relations(User, ({ many }) => ({
|
||||
auditLogs: many(AdminAuditLog),
|
||||
}));
|
||||
|
||||
export const websiteTicketRelations = relations(WebsiteTicket, ({ one, many }) => ({
|
||||
creator: one(User, {
|
||||
fields: [WebsiteTicket.creatorId],
|
||||
references: [User.id],
|
||||
relationName: "ticketCreator",
|
||||
export const websiteTicketRelations = relations(
|
||||
WebsiteTicket,
|
||||
({ one, many }) => ({
|
||||
creator: one(User, {
|
||||
fields: [WebsiteTicket.creatorId],
|
||||
references: [User.id],
|
||||
relationName: "ticketCreator",
|
||||
}),
|
||||
assignee: one(User, {
|
||||
fields: [WebsiteTicket.assigneeId],
|
||||
references: [User.id],
|
||||
relationName: "ticketAssignee",
|
||||
}),
|
||||
messages: many(WebsiteTicketMessage),
|
||||
}),
|
||||
assignee: one(User, {
|
||||
fields: [WebsiteTicket.assigneeId],
|
||||
references: [User.id],
|
||||
relationName: "ticketAssignee",
|
||||
}),
|
||||
messages: many(WebsiteTicketMessage),
|
||||
}));
|
||||
);
|
||||
|
||||
export const websiteTicketMessageRelations = relations(
|
||||
WebsiteTicketMessage,
|
||||
@@ -79,19 +82,25 @@ export const aclModelPermissionRelations = relations(
|
||||
}),
|
||||
);
|
||||
|
||||
export const websiteEventTypeRelations = relations(WebsiteEventType, ({ many }) => ({
|
||||
events: many(WebsiteEvent),
|
||||
}));
|
||||
|
||||
export const websiteEventRelations = relations(WebsiteEvent, ({ one, many }) => ({
|
||||
type: one(WebsiteEventType, {
|
||||
fields: [WebsiteEvent.typeId],
|
||||
references: [WebsiteEventType.id],
|
||||
export const websiteEventTypeRelations = relations(
|
||||
WebsiteEventType,
|
||||
({ many }) => ({
|
||||
events: many(WebsiteEvent),
|
||||
}),
|
||||
registrations: many(WebsiteEventRegistration),
|
||||
prizes: many(WebsiteEventPrize),
|
||||
winners: many(WebsiteEventWinner),
|
||||
}));
|
||||
);
|
||||
|
||||
export const websiteEventRelations = relations(
|
||||
WebsiteEvent,
|
||||
({ one, many }) => ({
|
||||
type: one(WebsiteEventType, {
|
||||
fields: [WebsiteEvent.typeId],
|
||||
references: [WebsiteEventType.id],
|
||||
}),
|
||||
registrations: many(WebsiteEventRegistration),
|
||||
prizes: many(WebsiteEventPrize),
|
||||
winners: many(WebsiteEventWinner),
|
||||
}),
|
||||
);
|
||||
|
||||
export const websiteEventRegistrationRelations = relations(
|
||||
WebsiteEventRegistration,
|
||||
@@ -103,19 +112,25 @@ export const websiteEventRegistrationRelations = relations(
|
||||
}),
|
||||
);
|
||||
|
||||
export const websiteEventPrizeRelations = relations(WebsiteEventPrize, ({ one }) => ({
|
||||
event: one(WebsiteEvent, {
|
||||
fields: [WebsiteEventPrize.eventId],
|
||||
references: [WebsiteEvent.id],
|
||||
export const websiteEventPrizeRelations = relations(
|
||||
WebsiteEventPrize,
|
||||
({ one }) => ({
|
||||
event: one(WebsiteEvent, {
|
||||
fields: [WebsiteEventPrize.eventId],
|
||||
references: [WebsiteEvent.id],
|
||||
}),
|
||||
}),
|
||||
}));
|
||||
);
|
||||
|
||||
export const websiteEventWinnerRelations = relations(WebsiteEventWinner, ({ one }) => ({
|
||||
event: one(WebsiteEvent, {
|
||||
fields: [WebsiteEventWinner.eventId],
|
||||
references: [WebsiteEvent.id],
|
||||
export const websiteEventWinnerRelations = relations(
|
||||
WebsiteEventWinner,
|
||||
({ one }) => ({
|
||||
event: one(WebsiteEvent, {
|
||||
fields: [WebsiteEventWinner.eventId],
|
||||
references: [WebsiteEvent.id],
|
||||
}),
|
||||
}),
|
||||
}));
|
||||
);
|
||||
|
||||
export const websitePollRelations = relations(WebsitePoll, ({ many }) => ({
|
||||
questions: many(WebsitePollQuestion),
|
||||
@@ -132,9 +147,12 @@ export const websitePollQuestionRelations = relations(
|
||||
}),
|
||||
);
|
||||
|
||||
export const websitePollVoteRelations = relations(WebsitePollVote, ({ one }) => ({
|
||||
question: one(WebsitePollQuestion, {
|
||||
fields: [WebsitePollVote.questionId],
|
||||
references: [WebsitePollQuestion.id],
|
||||
export const websitePollVoteRelations = relations(
|
||||
WebsitePollVote,
|
||||
({ one }) => ({
|
||||
question: one(WebsitePollQuestion, {
|
||||
fields: [WebsitePollVote.questionId],
|
||||
references: [WebsitePollQuestion.id],
|
||||
}),
|
||||
}),
|
||||
}));
|
||||
);
|
||||
@@ -5,9 +5,7 @@ export interface StaffActivityFilters {
|
||||
authorizationOnly?: boolean;
|
||||
}
|
||||
|
||||
export function buildStaffActivityWhere(
|
||||
filters: StaffActivityFilters,
|
||||
): any {
|
||||
export function buildStaffActivityWhere(filters: StaffActivityFilters): any {
|
||||
const where: any = {};
|
||||
if (filters.q?.trim())
|
||||
where.OR = [
|
||||
|
||||
@@ -75,4 +75,4 @@ describe("checkLogin", () => {
|
||||
expect(res.valid).toBe(true);
|
||||
expect(res.upgradedHash).toBeUndefined();
|
||||
});
|
||||
});
|
||||
});
|
||||
@@ -1,9 +1,5 @@
|
||||
import { randomBytes } from "node:crypto";
|
||||
import {
|
||||
bcrypt,
|
||||
bcryptVerify,
|
||||
md5,
|
||||
} from "hash-wasm";
|
||||
import { bcrypt, bcryptVerify, md5 } from "hash-wasm";
|
||||
|
||||
import { env } from "@/env";
|
||||
|
||||
@@ -59,4 +55,4 @@ export async function checkLogin(
|
||||
return { valid: true, upgradedHash: await hashPassword(password) };
|
||||
}
|
||||
return { valid: await verifyPassword(password, stored) };
|
||||
}
|
||||
}
|
||||
@@ -444,7 +444,9 @@ async function runFindMany(
|
||||
if (condition) stmt = stmt.where(condition);
|
||||
if (orderBy.length) stmt = stmt.orderBy(...orderBy);
|
||||
if (args.take !== undefined) stmt = stmt.limit(args.take);
|
||||
else if (args.skip) stmt = stmt.limit(18446744073709551615);
|
||||
else if (args.skip)
|
||||
// biome-ignore lint/correctness/noPrecisionLoss: SQL literal for BIGINT UNSIGNED max value (2^64-1 — exceeds JS number precision)
|
||||
stmt = stmt.limit(18446744073709551615);
|
||||
if (args.skip) stmt = stmt.offset(args.skip);
|
||||
|
||||
const rows = (await stmt) as any[];
|
||||
@@ -804,7 +806,9 @@ async function runGroupBy(
|
||||
}
|
||||
|
||||
if (args.take !== undefined) stmt = stmt.limit(args.take);
|
||||
else if (args.skip) stmt = stmt.limit(18446744073709551615);
|
||||
else if (args.skip)
|
||||
// biome-ignore lint/correctness/noPrecisionLoss: SQL literal for BIGINT UNSIGNED max value (2^64-1 — exceeds JS number precision)
|
||||
stmt = stmt.limit(18446744073709551615);
|
||||
if (args.skip) stmt = stmt.offset(args.skip);
|
||||
|
||||
const rows = (await stmt) as any[];
|
||||
@@ -871,6 +875,7 @@ class PrismaPromise<T> implements PromiseLike<T> {
|
||||
private readonly client: Client,
|
||||
) {}
|
||||
|
||||
// biome-ignore lint/suspicious/noThenProperty: Custom thenable for $transaction chaining — routes through Drizzle at runtime
|
||||
then<TResult1 = T, TResult2 = never>(
|
||||
onFulfilled?: ((value: T) => TResult1 | PromiseLike<TResult1>) | null,
|
||||
onRejected?: ((reason: any) => TResult2 | PromiseLike<TResult2>) | null,
|
||||
|
||||
+1
-1
@@ -1,6 +1,6 @@
|
||||
import type { PrismaClient } from "@/generated/prisma/client";
|
||||
import { makePrisma, Prisma as PrismaHelper } from "@/lib/prisma-facade";
|
||||
import { db } from "@/lib/db";
|
||||
import { makePrisma, Prisma as PrismaHelper } from "@/lib/prisma-facade";
|
||||
|
||||
export const prisma = makePrisma(db) as unknown as PrismaClient;
|
||||
export { PrismaHelper as Prisma };
|
||||
+1
-1
@@ -33,4 +33,4 @@
|
||||
".next/dev/types/**/*.ts"
|
||||
],
|
||||
"exclude": ["node_modules", "e2e", "playwright.config.ts"]
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user