diff options
| author | Fuwn <[email protected]> | 2026-03-01 16:20:51 -0800 |
|---|---|---|
| committer | Fuwn <[email protected]> | 2026-03-01 16:21:02 -0800 |
| commit | eae5d24d9e79e59a19d4721caaeaa0ca650ecb33 (patch) | |
| tree | 1b685bb248e051dfa26d2bfdebe6689402dd93c5 /src/graphql/user/resolvers.ts | |
| parent | chore(tooling): remove legacy eslint and prettier (diff) | |
| download | due.moe-eae5d24d9e79e59a19d4721caaeaa0ca650ecb33.tar.xz due.moe-eae5d24d9e79e59a19d4721caaeaa0ca650ecb33.zip | |
chore(biome): drop formatter style overrides
Diffstat (limited to 'src/graphql/user/resolvers.ts')
| -rw-r--r-- | src/graphql/user/resolvers.ts | 438 |
1 files changed, 235 insertions, 203 deletions
diff --git a/src/graphql/user/resolvers.ts b/src/graphql/user/resolvers.ts index 879d066d..986b9684 100644 --- a/src/graphql/user/resolvers.ts +++ b/src/graphql/user/resolvers.ts @@ -1,244 +1,276 @@ -import { userIdentity, type UserIdentity } from '$lib/Data/AniList/identity'; +import { userIdentity, type UserIdentity } from "$lib/Data/AniList/identity"; import { - addUserBadge, - getUserBadges, - removeAllUserBadges, - removeUserBadge, - setShadowHidden, - setShadowHiddenBadge, - updateUserBadge, - type Badge as DatabaseBadge -} from '$lib/Database/SB/User/badges'; -import type { WithIndex } from '../$types'; -import type { Resolvers as RootResolvers, Badge } from '../$types'; -import type { RequestEvent } from '@sveltejs/kit'; + addUserBadge, + getUserBadges, + removeAllUserBadges, + removeUserBadge, + setShadowHidden, + setShadowHiddenBadge, + updateUserBadge, + type Badge as DatabaseBadge, +} from "$lib/Database/SB/User/badges"; +import type { WithIndex } from "../$types"; +import type { Resolvers as RootResolvers, Badge } from "../$types"; +import type { RequestEvent } from "@sveltejs/kit"; import { - getUserPreferences, - setBiography, - setCSS, - setPinnedBadgeWallCategories, - toggleHideAWCBadges, - toggleHideMissingBadges, - toggleHololiveStreamPinning, - togglePinnedBadgeWallCategory, - type UserPreferences -} from '$lib/Database/SB/User/preferences'; -import privilegedUser from '$lib/Utility/privilegedUser'; + getUserPreferences, + setBiography, + setCSS, + setPinnedBadgeWallCategories, + toggleHideAWCBadges, + toggleHideMissingBadges, + toggleHololiveStreamPinning, + togglePinnedBadgeWallCategory, + type UserPreferences, +} from "$lib/Database/SB/User/preferences"; +import privilegedUser from "$lib/Utility/privilegedUser"; type Context = RequestEvent<Partial<Record<string, string>>, string | null>; -type UserResolvers = Pick<RootResolvers, 'Query' | 'Mutation' | 'User' | 'Badge' | 'Preferences'>; +type UserResolvers = Pick< + RootResolvers, + "Query" | "Mutation" | "User" | "Badge" | "Preferences" +>; const toGraphQLBadges = (databaseBadges: DatabaseBadge[]): Badge[] => - databaseBadges.map((databaseBadge) => ({ - id: databaseBadge.id ?? 0, - post: databaseBadge.post ?? '', - image: databaseBadge.image ?? '', - time: databaseBadge.time ?? new Date().toISOString(), - hidden: databaseBadge.hidden ?? false, - shadow_hidden: databaseBadge.shadow_hidden ?? false, - click_count: databaseBadge.click_count ?? 0, - category: databaseBadge.category ?? null, - description: databaseBadge.description ?? null, - source: databaseBadge.source ?? null, - designer: databaseBadge.designer ?? null - })); + databaseBadges.map((databaseBadge) => ({ + id: databaseBadge.id ?? 0, + post: databaseBadge.post ?? "", + image: databaseBadge.image ?? "", + time: databaseBadge.time ?? new Date().toISOString(), + hidden: databaseBadge.hidden ?? false, + shadow_hidden: databaseBadge.shadow_hidden ?? false, + click_count: databaseBadge.click_count ?? 0, + category: databaseBadge.category ?? null, + description: databaseBadge.description ?? null, + source: databaseBadge.source ?? null, + designer: databaseBadge.designer ?? null, + })); const auth = async (context: Context) => { - const userCookie = context.cookies.get('user'); + const userCookie = context.cookies.get("user"); - if (!userCookie) return Error('Unauthorised'); + if (!userCookie) return Error("Unauthorised"); - const user = JSON.parse(userCookie); + const user = JSON.parse(userCookie); - return await userIdentity({ - tokenType: user['token_type'], - expiresIn: user['expires_in'], - accessToken: user['access_token'], - refreshToken: user['refresh_token'] - }); + return await userIdentity({ + tokenType: user["token_type"], + expiresIn: user["expires_in"], + accessToken: user["access_token"], + refreshToken: user["refresh_token"], + }); }; const authenticatedBadgesOperation = async ( - context: Context, - operation: (identity: UserIdentity, authorised: boolean) => Promise<unknown> + context: Context, + operation: (identity: UserIdentity, authorised: boolean) => Promise<unknown>, ) => { - const identity = await auth(context); + const identity = await auth(context); - if (identity instanceof Error) throw new Error('Unauthorized'); + if (identity instanceof Error) throw new Error("Unauthorized"); - const authorised = privilegedUser(identity.id); + const authorised = privilegedUser(identity.id); - await operation(identity, authorised); + await operation(identity, authorised); - const databaseBadges = await getUserBadges(identity.id); - const badges = toGraphQLBadges(databaseBadges); + const databaseBadges = await getUserBadges(identity.id); + const badges = toGraphQLBadges(databaseBadges); - return { - id: identity.id, - badges, - preferences: null, - badgesCount: badges.length - }; + return { + id: identity.id, + badges, + preferences: null, + badgesCount: badges.length, + }; }; const authenticatedPreferencesOperation = async ( - context: Context, - operation: (identity: UserIdentity, authorised: boolean) => Promise<UserPreferences | null> + context: Context, + operation: ( + identity: UserIdentity, + authorised: boolean, + ) => Promise<UserPreferences | null>, ) => { - const identity = await auth(context); + const identity = await auth(context); - if (identity instanceof Error) throw new Error('Unauthorized'); + if (identity instanceof Error) throw new Error("Unauthorized"); - const authorised = privilegedUser(identity.id); + const authorised = privilegedUser(identity.id); - return { - id: identity.id, - badges: [] as Badge[], - preferences: await operation(identity, authorised), - badgesCount: 0 - }; + return { + id: identity.id, + badges: [] as Badge[], + preferences: await operation(identity, authorised), + badgesCount: 0, + }; }; const ensureOwnerOrPrivileged = ( - identity: UserIdentity, - authorised: boolean, - targetUserId: number + identity: UserIdentity, + authorised: boolean, + targetUserId: number, ) => { - if (!authorised && identity.id !== targetUserId) throw new Error('Unauthorized'); + if (!authorised && identity.id !== targetUserId) + throw new Error("Unauthorized"); }; const ensureBadgeOwnerOrPrivileged = async ( - identity: UserIdentity, - authorised: boolean, - badgeId: number + identity: UserIdentity, + authorised: boolean, + badgeId: number, ) => { - if (authorised) return; + if (authorised) return; - const ownsBadge = (await getUserBadges(identity.id)).some((badge) => badge.id === badgeId); + const ownsBadge = (await getUserBadges(identity.id)).some( + (badge) => badge.id === badgeId, + ); - if (!ownsBadge) throw new Error('Unauthorized'); + if (!ownsBadge) throw new Error("Unauthorized"); }; export const resolvers: WithIndex<UserResolvers> = { - Query: { - User: async (_, args) => { - if (!args.id) return null; - - const databaseBadges = await getUserBadges(args.id); - const badges = toGraphQLBadges(databaseBadges); - - return { - id: args.id, - badges, - preferences: await getUserPreferences(args.id), - badgesCount: badges.length - }; - }, - badges: async (_, args) => { - if (!args.id) return []; - - const databaseBadges = await getUserBadges(args.id, args.page || 0, args.size || 0); - - return toGraphQLBadges(databaseBadges); - } - }, - Mutation: { - shadowHideBadges: async (_, args, context) => - await authenticatedBadgesOperation(context, async (identity, authorised) => { - ensureOwnerOrPrivileged(identity, authorised, args.userId); - - await setShadowHidden(args.userId, authorised); - }), - shadowHideBadge: async (_, args, context) => - await authenticatedBadgesOperation(context, async (identity, authorised) => { - await ensureBadgeOwnerOrPrivileged(identity, authorised, args.id); - await setShadowHiddenBadge(args.id, args.state == null ? true : args.state); - }), - hideBadge: async (_, args, context) => - await authenticatedBadgesOperation(context, async (identity) => { - const allBadges = await getUserBadges(identity.id); - const category = args.category || ''; - - await Promise.all( - allBadges - .filter((badge) => badge.category === category) - .map(async (badge) => { - await updateUserBadge(identity.id, badge.id as number, { - ...badge, - hidden: - allBadges - .filter((badge) => badge.category === category) - .filter((badge) => badge.hidden).length > - allBadges.filter((badge) => badge.category === category).length / 2 - ? false - : true - }); - }) - ); - }), - updateBadge: async (_, args, context) => - await authenticatedBadgesOperation(context, async (identity) => { - const badge = { - post: args.post || undefined, - image: args.image || undefined, - description: args.description || null, - time: args.time || undefined, - category: args.category || null, - hidden: args.hidden || false, - source: args.source || null, - designer: args.designer || null - }; - - if ((await getUserBadges(identity.id)).find((badge) => badge.id === args.id)) { - await updateUserBadge(identity.id, args.id as number, badge); - } else { - await addUserBadge(identity.id, badge); - } - }), - deleteBadge: async (_, args, context) => - await authenticatedBadgesOperation( - context, - async (identity) => await removeUserBadge(identity.id, args.id) - ), - pruneUserBadges: async (_, __, context) => - await authenticatedBadgesOperation( - context as Context, - async (identity) => await removeAllUserBadges(identity.id) - ), - toggleHideMissingBadges: async (_, _args, context) => - await authenticatedPreferencesOperation( - context as Context, - async (identity) => await toggleHideMissingBadges(identity.id) - ), - toggleHideAWCBadges: async (_, _args, context) => - await authenticatedPreferencesOperation( - context as Context, - async (identity) => await toggleHideAWCBadges(identity.id) - ), - setBadgeWallCSS: async (_, args, context) => - await authenticatedPreferencesOperation( - context as Context, - async (identity) => await setCSS(identity.id, args.css) - ), - togglePinnedBadgeWallCategory: async (_, args, context) => - await authenticatedPreferencesOperation( - context as Context, - async (identity) => await togglePinnedBadgeWallCategory(identity.id, args.category) - ), - setPinnedBadgeWallCategories: async (_, args, context) => - await authenticatedPreferencesOperation( - context as Context, - async (identity) => await setPinnedBadgeWallCategories(identity.id, args.categories) - ), - setBiography: async (_, args, context) => - await authenticatedPreferencesOperation( - context as Context, - async (identity) => await setBiography(identity.id, args.biography.slice(0, 3000)) - ), - togglePinnedHololiveStream: async (_, args, context) => - await authenticatedPreferencesOperation( - context as Context, - async (identity) => await toggleHololiveStreamPinning(identity.id, args.stream) - ) - } + Query: { + User: async (_, args) => { + if (!args.id) return null; + + const databaseBadges = await getUserBadges(args.id); + const badges = toGraphQLBadges(databaseBadges); + + return { + id: args.id, + badges, + preferences: await getUserPreferences(args.id), + badgesCount: badges.length, + }; + }, + badges: async (_, args) => { + if (!args.id) return []; + + const databaseBadges = await getUserBadges( + args.id, + args.page || 0, + args.size || 0, + ); + + return toGraphQLBadges(databaseBadges); + }, + }, + Mutation: { + shadowHideBadges: async (_, args, context) => + await authenticatedBadgesOperation( + context, + async (identity, authorised) => { + ensureOwnerOrPrivileged(identity, authorised, args.userId); + + await setShadowHidden(args.userId, authorised); + }, + ), + shadowHideBadge: async (_, args, context) => + await authenticatedBadgesOperation( + context, + async (identity, authorised) => { + await ensureBadgeOwnerOrPrivileged(identity, authorised, args.id); + await setShadowHiddenBadge( + args.id, + args.state == null ? true : args.state, + ); + }, + ), + hideBadge: async (_, args, context) => + await authenticatedBadgesOperation(context, async (identity) => { + const allBadges = await getUserBadges(identity.id); + const category = args.category || ""; + + await Promise.all( + allBadges + .filter((badge) => badge.category === category) + .map(async (badge) => { + await updateUserBadge(identity.id, badge.id as number, { + ...badge, + hidden: + allBadges + .filter((badge) => badge.category === category) + .filter((badge) => badge.hidden).length > + allBadges.filter((badge) => badge.category === category) + .length / + 2 + ? false + : true, + }); + }), + ); + }), + updateBadge: async (_, args, context) => + await authenticatedBadgesOperation(context, async (identity) => { + const badge = { + post: args.post || undefined, + image: args.image || undefined, + description: args.description || null, + time: args.time || undefined, + category: args.category || null, + hidden: args.hidden || false, + source: args.source || null, + designer: args.designer || null, + }; + + if ( + (await getUserBadges(identity.id)).find( + (badge) => badge.id === args.id, + ) + ) { + await updateUserBadge(identity.id, args.id as number, badge); + } else { + await addUserBadge(identity.id, badge); + } + }), + deleteBadge: async (_, args, context) => + await authenticatedBadgesOperation( + context, + async (identity) => await removeUserBadge(identity.id, args.id), + ), + pruneUserBadges: async (_, __, context) => + await authenticatedBadgesOperation( + context as Context, + async (identity) => await removeAllUserBadges(identity.id), + ), + toggleHideMissingBadges: async (_, _args, context) => + await authenticatedPreferencesOperation( + context as Context, + async (identity) => await toggleHideMissingBadges(identity.id), + ), + toggleHideAWCBadges: async (_, _args, context) => + await authenticatedPreferencesOperation( + context as Context, + async (identity) => await toggleHideAWCBadges(identity.id), + ), + setBadgeWallCSS: async (_, args, context) => + await authenticatedPreferencesOperation( + context as Context, + async (identity) => await setCSS(identity.id, args.css), + ), + togglePinnedBadgeWallCategory: async (_, args, context) => + await authenticatedPreferencesOperation( + context as Context, + async (identity) => + await togglePinnedBadgeWallCategory(identity.id, args.category), + ), + setPinnedBadgeWallCategories: async (_, args, context) => + await authenticatedPreferencesOperation( + context as Context, + async (identity) => + await setPinnedBadgeWallCategories(identity.id, args.categories), + ), + setBiography: async (_, args, context) => + await authenticatedPreferencesOperation( + context as Context, + async (identity) => + await setBiography(identity.id, args.biography.slice(0, 3000)), + ), + togglePinnedHololiveStream: async (_, args, context) => + await authenticatedPreferencesOperation( + context as Context, + async (identity) => + await toggleHololiveStreamPinning(identity.id, args.stream), + ), + }, }; |