rhythia-api 231.0.0 → 234.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (90) hide show
  1. package/.codex +0 -0
  2. package/.env +1 -12
  3. package/README.md +4 -4
  4. package/api/acceptInvite.ts +1 -1
  5. package/api/addCollectionMap.ts +1 -1
  6. package/api/chartPublicStats.ts +1 -1
  7. package/api/checkQualified.ts +93 -83
  8. package/api/createBeatmap.ts +53 -62
  9. package/api/createBeatmapPage.ts +1 -1
  10. package/api/createClan.ts +1 -1
  11. package/api/createCollection.ts +1 -1
  12. package/api/createInvite.ts +1 -1
  13. package/api/createSupporter.ts +1 -1
  14. package/api/deleteBeatmapPage.ts +2 -5
  15. package/api/deleteCollection.ts +1 -1
  16. package/api/deleteCollectionMap.ts +1 -1
  17. package/api/editAboutMe.ts +1 -1
  18. package/api/editClan.ts +1 -1
  19. package/api/editCollection.ts +1 -2
  20. package/api/editProfile.ts +1 -1
  21. package/api/enhancedSearch.ts +113 -0
  22. package/api/executeAdminOperation.ts +1 -22
  23. package/api/getAvatarUploadUrl.ts +1 -1
  24. package/api/getBadgeLeaders.ts +1 -1
  25. package/api/getBadgedUsers.ts +1 -1
  26. package/api/getBeatmapComments.ts +1 -1
  27. package/api/getBeatmapPage.ts +74 -106
  28. package/api/getBeatmapPageById.ts +70 -109
  29. package/api/getBeatmapStarRating.ts +1 -1
  30. package/api/getBeatmaps.ts +1 -1
  31. package/api/getClan.ts +1 -1
  32. package/api/getClans.ts +1 -1
  33. package/api/getCollection.ts +1 -1
  34. package/api/getCollections.ts +1 -1
  35. package/api/getInventory.ts +1 -1
  36. package/api/getLeaderboard.ts +1 -1
  37. package/api/getMapUploadUrl.ts +2 -2
  38. package/api/getOnlinePlayers.ts +1 -1
  39. package/api/getPassToken.ts +1 -1
  40. package/api/getProfile.ts +51 -31
  41. package/api/getPublicStats.ts +5 -5
  42. package/api/getRawStarRating.ts +1 -1
  43. package/api/getScore.ts +1 -1
  44. package/api/getStoryBeatmaps.ts +1 -1
  45. package/api/getTimestamp.ts +1 -1
  46. package/api/getUserScores.ts +19 -19
  47. package/api/getVerified.ts +1 -1
  48. package/api/getVideoUploadUrl.ts +1 -1
  49. package/api/postBeatmapComment.ts +1 -1
  50. package/api/qualifyMap.ts +97 -86
  51. package/api/rankMapsArchive.ts +8 -1
  52. package/api/searchUsers.ts +1 -1
  53. package/api/setPasskey.ts +1 -1
  54. package/api/submitScore.ts +1 -6
  55. package/api/submitScoreInternal.ts +461 -449
  56. package/api/updateBeatmapPage.ts +1 -1
  57. package/api/vetoMap.ts +101 -94
  58. package/index.ts +173 -120
  59. package/package.json +7 -12
  60. package/queries/admin_delete_user.sql +39 -39
  61. package/queries/admin_exclude_user.sql +21 -21
  62. package/queries/admin_invalidate_ranked_scores.sql +18 -18
  63. package/queries/admin_log_action.sql +10 -10
  64. package/queries/admin_profanity_clear.sql +29 -29
  65. package/queries/admin_remove_all_scores.sql +29 -29
  66. package/queries/admin_restrict_user.sql +21 -21
  67. package/queries/admin_search_users.sql +24 -24
  68. package/queries/admin_silence_user.sql +21 -21
  69. package/queries/admin_unban_user.sql +21 -21
  70. package/queries/enhanced_search.sql +217 -0
  71. package/queries/get_badge_leaderboard.sql +50 -50
  72. package/queries/get_clan_leaderboard.sql +68 -68
  73. package/queries/get_collections_v4.sql +109 -109
  74. package/queries/get_top_scores_for_beatmap.sql +44 -44
  75. package/queries/get_top_scores_for_beatmap3.sql +38 -0
  76. package/queries/get_user_by_email.sql +32 -32
  77. package/queries/get_user_scores_lastday.sql +47 -47
  78. package/queries/get_user_scores_reign.sql +31 -31
  79. package/queries/get_user_scores_top_and_stats.sql +84 -84
  80. package/queries/grant_special_badges.sql +69 -69
  81. package/types/database.ts +1288 -1224
  82. package/utils/beatmapTopScores.ts +84 -0
  83. package/utils/mapLifecycleWebhook.ts +287 -0
  84. package/utils/requestGeo.ts +13 -0
  85. package/utils/requestUtils.ts +127 -127
  86. package/utils/response.ts +11 -0
  87. package/worker.ts +189 -0
  88. package/wrangler.jsonc +10 -0
  89. package/index.html +0 -3
  90. package/vercel.json +0 -13
@@ -1,39 +1,39 @@
1
- CREATE OR REPLACE FUNCTION public.admin_delete_user(user_id integer)
2
- RETURNS boolean
3
- LANGUAGE plpgsql
4
- SECURITY DEFINER
5
- AS $function$
6
- DECLARE
7
- success BOOLEAN;
8
- BEGIN
9
- -- Delete scores first due to foreign key constraints
10
- DELETE FROM public.scores WHERE "userId" = user_id;
11
-
12
- -- Delete beatmapPageComments
13
- DELETE FROM public."beatmapPageComments" WHERE owner = user_id;
14
-
15
- -- Delete beatmapPages owned by user
16
- DELETE FROM public."beatmapPages" WHERE owner = user_id;
17
-
18
- -- Delete collections owned by user
19
- DELETE FROM public."beatmapCollections" WHERE owner = user_id;
20
-
21
- -- Delete collection relations related to user's collections
22
- -- (this is handled by cascade if you have it set up)
23
-
24
- -- Delete passkeys
25
- DELETE FROM public.passkeys WHERE id = user_id;
26
-
27
- -- Delete profile activity
28
- DELETE FROM public."profileActivities"
29
- WHERE uid = (SELECT uid FROM public.profiles WHERE id = user_id);
30
-
31
- -- Finally, delete the profile
32
- DELETE FROM public.profiles WHERE id = user_id;
33
-
34
- -- Check if deletion was successful
35
- success := NOT EXISTS (SELECT 1 FROM public.profiles WHERE id = user_id);
36
-
37
- RETURN success;
38
- END;
39
- $function$
1
+ CREATE OR REPLACE FUNCTION public.admin_delete_user(user_id integer)
2
+ RETURNS boolean
3
+ LANGUAGE plpgsql
4
+ SECURITY DEFINER
5
+ AS $function$
6
+ DECLARE
7
+ success BOOLEAN;
8
+ BEGIN
9
+ -- Delete scores first due to foreign key constraints
10
+ DELETE FROM public.scores WHERE "userId" = user_id;
11
+
12
+ -- Delete beatmapPageComments
13
+ DELETE FROM public."beatmapPageComments" WHERE owner = user_id;
14
+
15
+ -- Delete beatmapPages owned by user
16
+ DELETE FROM public."beatmapPages" WHERE owner = user_id;
17
+
18
+ -- Delete collections owned by user
19
+ DELETE FROM public."beatmapCollections" WHERE owner = user_id;
20
+
21
+ -- Delete collection relations related to user's collections
22
+ -- (this is handled by cascade if you have it set up)
23
+
24
+ -- Delete passkeys
25
+ DELETE FROM public.passkeys WHERE id = user_id;
26
+
27
+ -- Delete profile activity
28
+ DELETE FROM public."profileActivities"
29
+ WHERE uid = (SELECT uid FROM public.profiles WHERE id = user_id);
30
+
31
+ -- Finally, delete the profile
32
+ DELETE FROM public.profiles WHERE id = user_id;
33
+
34
+ -- Check if deletion was successful
35
+ success := NOT EXISTS (SELECT 1 FROM public.profiles WHERE id = user_id);
36
+
37
+ RETURN success;
38
+ END;
39
+ $function$
@@ -1,21 +1,21 @@
1
- CREATE OR REPLACE FUNCTION public.admin_exclude_user(user_id integer)
2
- RETURNS boolean
3
- LANGUAGE plpgsql
4
- SECURITY DEFINER
5
- AS $function$
6
- DECLARE
7
- success BOOLEAN;
8
- BEGIN
9
- UPDATE public.profiles
10
- SET ban = 'excluded'::"banTypes",
11
- "bannedAt" = EXTRACT(EPOCH FROM NOW())::bigint
12
- WHERE id = user_id;
13
-
14
- success := EXISTS (
15
- SELECT 1 FROM public.profiles
16
- WHERE id = user_id AND ban = 'excluded'::"banTypes"
17
- );
18
-
19
- RETURN success;
20
- END;
21
- $function$
1
+ CREATE OR REPLACE FUNCTION public.admin_exclude_user(user_id integer)
2
+ RETURNS boolean
3
+ LANGUAGE plpgsql
4
+ SECURITY DEFINER
5
+ AS $function$
6
+ DECLARE
7
+ success BOOLEAN;
8
+ BEGIN
9
+ UPDATE public.profiles
10
+ SET ban = 'excluded'::"banTypes",
11
+ "bannedAt" = EXTRACT(EPOCH FROM NOW())::bigint
12
+ WHERE id = user_id;
13
+
14
+ success := EXISTS (
15
+ SELECT 1 FROM public.profiles
16
+ WHERE id = user_id AND ban = 'excluded'::"banTypes"
17
+ );
18
+
19
+ RETURN success;
20
+ END;
21
+ $function$
@@ -1,18 +1,18 @@
1
- CREATE OR REPLACE FUNCTION public.admin_invalidate_ranked_scores(user_id integer)
2
- RETURNS integer
3
- LANGUAGE plpgsql
4
- SECURITY DEFINER
5
- AS $function$
6
- DECLARE
7
- updated_count INTEGER;
8
- BEGIN
9
- -- Update user stats to reflect score invalidation
10
- UPDATE public.profiles
11
- SET
12
- skill_points = 0,
13
- spin_skill_points = 0
14
- WHERE id = user_id;
15
-
16
- RETURN updated_count;
17
- END;
18
- $function$
1
+ CREATE OR REPLACE FUNCTION public.admin_invalidate_ranked_scores(user_id integer)
2
+ RETURNS integer
3
+ LANGUAGE plpgsql
4
+ SECURITY DEFINER
5
+ AS $function$
6
+ DECLARE
7
+ updated_count INTEGER;
8
+ BEGIN
9
+ -- Update user stats to reflect score invalidation
10
+ UPDATE public.profiles
11
+ SET
12
+ skill_points = 0,
13
+ spin_skill_points = 0
14
+ WHERE id = user_id;
15
+
16
+ RETURN updated_count;
17
+ END;
18
+ $function$
@@ -1,10 +1,10 @@
1
- CREATE OR REPLACE FUNCTION public.admin_log_action(admin_id integer, action_type text, target_id integer, details jsonb DEFAULT NULL::jsonb)
2
- RETURNS void
3
- LANGUAGE plpgsql
4
- SECURITY DEFINER
5
- AS $function$
6
- BEGIN
7
- INSERT INTO public.admin_actions (admin_id, action_type, target_id, details)
8
- VALUES (admin_id, action_type, target_id, details);
9
- END;
10
- $function$
1
+ CREATE OR REPLACE FUNCTION public.admin_log_action(admin_id integer, action_type text, target_id integer, details jsonb DEFAULT NULL::jsonb)
2
+ RETURNS void
3
+ LANGUAGE plpgsql
4
+ SECURITY DEFINER
5
+ AS $function$
6
+ BEGIN
7
+ INSERT INTO public.admin_actions (admin_id, action_type, target_id, details)
8
+ VALUES (admin_id, action_type, target_id, details);
9
+ END;
10
+ $function$
@@ -1,29 +1,29 @@
1
- CREATE OR REPLACE FUNCTION public.admin_profanity_clear(user_id integer)
2
- RETURNS boolean
3
- LANGUAGE plpgsql
4
- SECURITY DEFINER
5
- AS $function$
6
- DECLARE
7
- success BOOLEAN;
8
- random_username TEXT;
9
- BEGIN
10
- -- Generate a random username (Player + random number between 10000-99999)
11
- random_username := 'Player' || (10000 + floor(random() * 90000)::int)::text;
12
-
13
- -- Update the profile
14
- UPDATE public.profiles
15
- SET
16
- username = random_username,
17
- "computedUsername" = LOWER(random_username),
18
- about_me = NULL
19
- WHERE id = user_id;
20
-
21
- -- Check if update was successful
22
- success := EXISTS (
23
- SELECT 1 FROM public.profiles
24
- WHERE id = user_id AND username = random_username AND about_me IS NULL
25
- );
26
-
27
- RETURN success;
28
- END;
29
- $function$
1
+ CREATE OR REPLACE FUNCTION public.admin_profanity_clear(user_id integer)
2
+ RETURNS boolean
3
+ LANGUAGE plpgsql
4
+ SECURITY DEFINER
5
+ AS $function$
6
+ DECLARE
7
+ success BOOLEAN;
8
+ random_username TEXT;
9
+ BEGIN
10
+ -- Generate a random username (Player + random number between 10000-99999)
11
+ random_username := 'Player' || (10000 + floor(random() * 90000)::int)::text;
12
+
13
+ -- Update the profile
14
+ UPDATE public.profiles
15
+ SET
16
+ username = random_username,
17
+ "computedUsername" = LOWER(random_username),
18
+ about_me = NULL
19
+ WHERE id = user_id;
20
+
21
+ -- Check if update was successful
22
+ success := EXISTS (
23
+ SELECT 1 FROM public.profiles
24
+ WHERE id = user_id AND username = random_username AND about_me IS NULL
25
+ );
26
+
27
+ RETURN success;
28
+ END;
29
+ $function$
@@ -1,29 +1,29 @@
1
- CREATE OR REPLACE FUNCTION public.admin_remove_all_scores(user_id integer)
2
- RETURNS integer
3
- LANGUAGE plpgsql
4
- SECURITY DEFINER
5
- AS $function$
6
- DECLARE
7
- deleted_count INTEGER;
8
- BEGIN
9
- -- Delete all scores for this user and count them
10
- WITH deleted AS (
11
- DELETE FROM public.scores
12
- WHERE "userId" = user_id
13
- RETURNING *
14
- )
15
- SELECT COUNT(*) INTO deleted_count FROM deleted;
16
-
17
- -- Update user stats to reflect score removal
18
- UPDATE public.profiles
19
- SET
20
- play_count = 0,
21
- squares_hit = 0,
22
- total_score = 0,
23
- skill_points = 0,
24
- spin_skill_points = 0
25
- WHERE id = user_id;
26
-
27
- RETURN deleted_count;
28
- END;
29
- $function$
1
+ CREATE OR REPLACE FUNCTION public.admin_remove_all_scores(user_id integer)
2
+ RETURNS integer
3
+ LANGUAGE plpgsql
4
+ SECURITY DEFINER
5
+ AS $function$
6
+ DECLARE
7
+ deleted_count INTEGER;
8
+ BEGIN
9
+ -- Delete all scores for this user and count them
10
+ WITH deleted AS (
11
+ DELETE FROM public.scores
12
+ WHERE "userId" = user_id
13
+ RETURNING *
14
+ )
15
+ SELECT COUNT(*) INTO deleted_count FROM deleted;
16
+
17
+ -- Update user stats to reflect score removal
18
+ UPDATE public.profiles
19
+ SET
20
+ play_count = 0,
21
+ squares_hit = 0,
22
+ total_score = 0,
23
+ skill_points = 0,
24
+ spin_skill_points = 0
25
+ WHERE id = user_id;
26
+
27
+ RETURN deleted_count;
28
+ END;
29
+ $function$
@@ -1,21 +1,21 @@
1
- CREATE OR REPLACE FUNCTION public.admin_restrict_user(user_id integer)
2
- RETURNS boolean
3
- LANGUAGE plpgsql
4
- SECURITY DEFINER
5
- AS $function$
6
- DECLARE
7
- success BOOLEAN;
8
- BEGIN
9
- UPDATE public.profiles
10
- SET ban = 'restricted'::"banTypes",
11
- "bannedAt" = EXTRACT(EPOCH FROM NOW())::bigint
12
- WHERE id = user_id;
13
-
14
- success := EXISTS (
15
- SELECT 1 FROM public.profiles
16
- WHERE id = user_id AND ban = 'restricted'::"banTypes"
17
- );
18
-
19
- RETURN success;
20
- END;
21
- $function$
1
+ CREATE OR REPLACE FUNCTION public.admin_restrict_user(user_id integer)
2
+ RETURNS boolean
3
+ LANGUAGE plpgsql
4
+ SECURITY DEFINER
5
+ AS $function$
6
+ DECLARE
7
+ success BOOLEAN;
8
+ BEGIN
9
+ UPDATE public.profiles
10
+ SET ban = 'restricted'::"banTypes",
11
+ "bannedAt" = EXTRACT(EPOCH FROM NOW())::bigint
12
+ WHERE id = user_id;
13
+
14
+ success := EXISTS (
15
+ SELECT 1 FROM public.profiles
16
+ WHERE id = user_id AND ban = 'restricted'::"banTypes"
17
+ );
18
+
19
+ RETURN success;
20
+ END;
21
+ $function$
@@ -1,24 +1,24 @@
1
- CREATE OR REPLACE FUNCTION public.admin_search_users(search_text text)
2
- RETURNS SETOF profiles
3
- LANGUAGE plpgsql
4
- SECURITY DEFINER
5
- AS $function$
6
- BEGIN
7
- RETURN QUERY
8
- SELECT *
9
- FROM public.profiles
10
- WHERE
11
- username ILIKE '%' || search_text || '%'
12
- OR "computedUsername" ILIKE '%' || search_text || '%'
13
- OR CAST(uid AS TEXT) ILIKE '%' || search_text || '%'
14
- OR CAST(id AS TEXT) = search_text
15
- OR about_me ILIKE '%' || search_text || '%'
16
- OR flag ILIKE '%' || search_text || '%'
17
- OR EXISTS (
18
- SELECT 1
19
- FROM public.passkeys
20
- WHERE passkeys.id = profiles.id AND passkeys.email ILIKE '%' || search_text || '%'
21
- )
22
- ORDER BY id;
23
- END;
24
- $function$
1
+ CREATE OR REPLACE FUNCTION public.admin_search_users(search_text text)
2
+ RETURNS SETOF profiles
3
+ LANGUAGE plpgsql
4
+ SECURITY DEFINER
5
+ AS $function$
6
+ BEGIN
7
+ RETURN QUERY
8
+ SELECT *
9
+ FROM public.profiles
10
+ WHERE
11
+ username ILIKE '%' || search_text || '%'
12
+ OR "computedUsername" ILIKE '%' || search_text || '%'
13
+ OR CAST(uid AS TEXT) ILIKE '%' || search_text || '%'
14
+ OR CAST(id AS TEXT) = search_text
15
+ OR about_me ILIKE '%' || search_text || '%'
16
+ OR flag ILIKE '%' || search_text || '%'
17
+ OR EXISTS (
18
+ SELECT 1
19
+ FROM public.passkeys
20
+ WHERE passkeys.id = profiles.id AND passkeys.email ILIKE '%' || search_text || '%'
21
+ )
22
+ ORDER BY id;
23
+ END;
24
+ $function$
@@ -1,21 +1,21 @@
1
- CREATE OR REPLACE FUNCTION public.admin_silence_user(user_id integer)
2
- RETURNS boolean
3
- LANGUAGE plpgsql
4
- SECURITY DEFINER
5
- AS $function$
6
- DECLARE
7
- success BOOLEAN;
8
- BEGIN
9
- UPDATE public.profiles
10
- SET ban = 'silenced'::"banTypes",
11
- "bannedAt" = EXTRACT(EPOCH FROM NOW())::bigint
12
- WHERE id = user_id;
13
-
14
- success := EXISTS (
15
- SELECT 1 FROM public.profiles
16
- WHERE id = user_id AND ban = 'silenced'::"banTypes"
17
- );
18
-
19
- RETURN success;
20
- END;
21
- $function$
1
+ CREATE OR REPLACE FUNCTION public.admin_silence_user(user_id integer)
2
+ RETURNS boolean
3
+ LANGUAGE plpgsql
4
+ SECURITY DEFINER
5
+ AS $function$
6
+ DECLARE
7
+ success BOOLEAN;
8
+ BEGIN
9
+ UPDATE public.profiles
10
+ SET ban = 'silenced'::"banTypes",
11
+ "bannedAt" = EXTRACT(EPOCH FROM NOW())::bigint
12
+ WHERE id = user_id;
13
+
14
+ success := EXISTS (
15
+ SELECT 1 FROM public.profiles
16
+ WHERE id = user_id AND ban = 'silenced'::"banTypes"
17
+ );
18
+
19
+ RETURN success;
20
+ END;
21
+ $function$
@@ -1,21 +1,21 @@
1
- CREATE OR REPLACE FUNCTION public.admin_unban_user(user_id integer)
2
- RETURNS boolean
3
- LANGUAGE plpgsql
4
- SECURITY DEFINER
5
- AS $function$
6
- DECLARE
7
- success BOOLEAN;
8
- BEGIN
9
- UPDATE public.profiles
10
- SET ban = 'cool',
11
- "bannedAt" = NULL
12
- WHERE id = user_id;
13
-
14
- success := EXISTS (
15
- SELECT 1 FROM public.profiles
16
- WHERE id = user_id AND ban IS NULL
17
- );
18
-
19
- RETURN success;
20
- END;
21
- $function$
1
+ CREATE OR REPLACE FUNCTION public.admin_unban_user(user_id integer)
2
+ RETURNS boolean
3
+ LANGUAGE plpgsql
4
+ SECURITY DEFINER
5
+ AS $function$
6
+ DECLARE
7
+ success BOOLEAN;
8
+ BEGIN
9
+ UPDATE public.profiles
10
+ SET ban = 'cool',
11
+ "bannedAt" = NULL
12
+ WHERE id = user_id;
13
+
14
+ success := EXISTS (
15
+ SELECT 1 FROM public.profiles
16
+ WHERE id = user_id AND ban IS NULL
17
+ );
18
+
19
+ RETURN success;
20
+ END;
21
+ $function$