refactor: replace all explicit any types with proper TypeScript types
Backend resolvers: typed enrichArticle/enrichVideo/enrichModel with DB and $inferSelect types, SQL<unknown>[] for conditions arrays, proper enum casts for status/role fields, $inferInsert for .set() updates, typed raw SQL result rows in gamification, ReplyLike interface for ctx.reply in auth. Frontend: typed catch blocks with Error/interface casts, isActiveLink param, adminGetUser response, tags filter callback. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -28,10 +28,12 @@ import {
|
||||
lt,
|
||||
gte,
|
||||
arrayContains,
|
||||
type SQL,
|
||||
} from "drizzle-orm";
|
||||
import { requireAdmin } from "../../lib/acl";
|
||||
import type { DB } from "../../db/connection";
|
||||
|
||||
async function enrichVideo(db: any, video: any) {
|
||||
async function enrichVideo(db: DB, video: typeof videos.$inferSelect) {
|
||||
// Fetch models
|
||||
const modelRows = await db
|
||||
.select({
|
||||
@@ -87,7 +89,7 @@ builder.queryField("videos", (t) =>
|
||||
const pageSize = args.limit ?? 24;
|
||||
const offset = args.offset ?? 0;
|
||||
|
||||
const conditions: any[] = [lte(videos.upload_date, new Date())];
|
||||
const conditions: SQL<unknown>[] = [lte(videos.upload_date, new Date())];
|
||||
if (!ctx.currentUser) conditions.push(eq(videos.premium, false));
|
||||
if (args.featured !== null && args.featured !== undefined) {
|
||||
conditions.push(eq(videos.featured, args.featured));
|
||||
@@ -107,7 +109,7 @@ builder.queryField("videos", (t) =>
|
||||
conditions.push(
|
||||
inArray(
|
||||
videos.id,
|
||||
videoIds.map((v: any) => v.video_id),
|
||||
videoIds.map((v) => v.video_id),
|
||||
),
|
||||
);
|
||||
}
|
||||
@@ -148,8 +150,8 @@ builder.queryField("videos", (t) =>
|
||||
.leftJoin(files, eq(videos.movie, files.id))
|
||||
.where(fullWhere),
|
||||
]);
|
||||
const videoList = rows.map((r: any) => r.v || r);
|
||||
const items = await Promise.all(videoList.map((v: any) => enrichVideo(ctx.db, v)));
|
||||
const videoList = rows.map((r) => r.v);
|
||||
const items = await Promise.all(videoList.map((v) => enrichVideo(ctx.db, v)));
|
||||
return { items, total: totalRows[0]?.total ?? 0 };
|
||||
}
|
||||
|
||||
@@ -157,7 +159,7 @@ builder.queryField("videos", (t) =>
|
||||
ctx.db.select().from(videos).where(where).orderBy(order).limit(pageSize).offset(offset),
|
||||
ctx.db.select({ total: count() }).from(videos).where(where),
|
||||
]);
|
||||
const items = await Promise.all(rows.map((v: any) => enrichVideo(ctx.db, v)));
|
||||
const items = await Promise.all(rows.map((v) => enrichVideo(ctx.db, v)));
|
||||
return { items, total: totalRows[0]?.total ?? 0 };
|
||||
},
|
||||
}),
|
||||
@@ -421,7 +423,7 @@ builder.queryField("analytics", (t) =>
|
||||
};
|
||||
}
|
||||
|
||||
const videoIds = modelVideoIds.map((v: any) => v.video_id);
|
||||
const videoIds = modelVideoIds.map((v) => v.video_id);
|
||||
const videoList = await ctx.db.select().from(videos).where(inArray(videos.id, videoIds));
|
||||
const plays = await ctx.db
|
||||
.select()
|
||||
@@ -435,14 +437,14 @@ builder.queryField("analytics", (t) =>
|
||||
const totalLikes = videoList.reduce((sum, v) => sum + (v.likes_count || 0), 0);
|
||||
const totalPlays = videoList.reduce((sum, v) => sum + (v.plays_count || 0), 0);
|
||||
|
||||
const playsByDate = plays.reduce((acc: any, play) => {
|
||||
const playsByDate = plays.reduce((acc: Record<string, number>, play) => {
|
||||
const date = new Date(play.date_created).toISOString().split("T")[0];
|
||||
if (!acc[date]) acc[date] = 0;
|
||||
acc[date]++;
|
||||
return acc;
|
||||
}, {});
|
||||
|
||||
const likesByDate = likes.reduce((acc: any, like) => {
|
||||
const likesByDate = likes.reduce((acc: Record<string, number>, like) => {
|
||||
const date = new Date(like.date_created).toISOString().split("T")[0];
|
||||
if (!acc[date]) acc[date] = 0;
|
||||
acc[date]++;
|
||||
@@ -499,7 +501,7 @@ builder.queryField("adminListVideos", (t) =>
|
||||
const limit = args.limit ?? 50;
|
||||
const offset = args.offset ?? 0;
|
||||
|
||||
const conditions: any[] = [];
|
||||
const conditions: SQL<unknown>[] = [];
|
||||
if (args.search) conditions.push(ilike(videos.title, `%${args.search}%`));
|
||||
if (args.premium !== null && args.premium !== undefined)
|
||||
conditions.push(eq(videos.premium, args.premium));
|
||||
@@ -517,7 +519,7 @@ builder.queryField("adminListVideos", (t) =>
|
||||
.offset(offset),
|
||||
ctx.db.select({ total: count() }).from(videos).where(where),
|
||||
]);
|
||||
const items = await Promise.all(rows.map((v: any) => enrichVideo(ctx.db, v)));
|
||||
const items = await Promise.all(rows.map((v) => enrichVideo(ctx.db, v)));
|
||||
return { items, total: totalRows[0]?.total ?? 0 };
|
||||
},
|
||||
}),
|
||||
@@ -590,7 +592,7 @@ builder.mutationField("updateVideo", (t) =>
|
||||
|
||||
const updated = await ctx.db
|
||||
.update(videos)
|
||||
.set(updates as any)
|
||||
.set(updates as Partial<typeof videos.$inferInsert>)
|
||||
.where(eq(videos.id, args.id))
|
||||
.returning();
|
||||
if (!updated[0]) return null;
|
||||
|
||||
Reference in New Issue
Block a user