aboutsummaryrefslogtreecommitdiff
path: root/src/graphql/user/resolvers.ts
diff options
context:
space:
mode:
authorFuwn <[email protected]>2026-03-01 16:20:51 -0800
committerFuwn <[email protected]>2026-03-01 16:21:02 -0800
commiteae5d24d9e79e59a19d4721caaeaa0ca650ecb33 (patch)
tree1b685bb248e051dfa26d2bfdebe6689402dd93c5 /src/graphql/user/resolvers.ts
parentchore(tooling): remove legacy eslint and prettier (diff)
downloaddue.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.ts438
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),
+ ),
+ },
};