rhythia-api 242.0.0 → 244.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.
- package/api/createBeatmap.ts +64 -40
- package/api/editProfile.ts +4 -67
- package/api/executeAdminOperation.ts +637 -27
- package/api/getAvatarUploadUrl.ts +90 -85
- package/api/getBeatmapPage.ts +2 -0
- package/api/getBeatmapPageById.ts +2 -0
- package/api/getBeatmaps.ts +110 -197
- package/api/getChangelog.ts +46 -0
- package/api/getCollection.ts +44 -31
- package/api/getMapUploadUrl.ts +90 -93
- package/api/getProfile.ts +297 -297
- package/api/getScore.ts +2 -0
- package/api/getVideoUploadUrl.ts +90 -85
- package/api/submitScoreInternal.ts +506 -461
- package/api/updateBeatmapPage.ts +6 -0
- package/beatmap-file-urls.json +29398 -0
- package/handleApi.ts +7 -4
- package/index.ts +193 -162
- package/package.json +7 -3
- package/queries/admin_delete_user.sql +42 -39
- package/queries/admin_remove_all_scores.sql +6 -3
- package/queries/admin_remove_score.sql +107 -0
- package/queries/admin_update_profile.sql +22 -0
- package/queries/get_beatmaps_v2.sql +48 -0
- package/queries/get_top_scores_for_beatmap3.sql +47 -38
- package/queries/profile_update_guards.sql +66 -0
- package/supabase/.temp/cli-latest +1 -0
- package/supabase/.temp/linked-project.json +1 -0
- package/types/database.ts +1702 -1450
- package/utils/beatmapFiles.ts +102 -0
- package/utils/beatmapHash.ts +239 -0
- package/utils/beatmapTopScores.ts +68 -84
- package/utils/getUserBySession.ts +3 -1
- package/utils/moderation.ts +101 -0
- package/utils/profileUpdateValidation.ts +51 -0
- package/utils/redis.ts +24 -0
- package/utils/requestUtils.ts +2 -2
- package/utils/rhrReplay.ts +122 -0
- package/utils/star-calc/formatSingle.ts +107 -0
- package/utils/star-calc/rhmParser.ts +214 -0
- package/utils/star-calc/sspmParser.ts +294 -160
- package/worker.ts +197 -195
- package/.env +0 -1
package/handleApi.ts
CHANGED
|
@@ -1,17 +1,20 @@
|
|
|
1
1
|
import { z } from "zod";
|
|
2
|
-
let
|
|
2
|
+
let endpoint = "https://development.rhythia.com";
|
|
3
3
|
import { profanity, CensorType } from "@2toad/profanity";
|
|
4
4
|
export function setEnvironment(
|
|
5
5
|
stage: "development" | "testing" | "production"
|
|
6
6
|
) {
|
|
7
|
-
|
|
7
|
+
endpoint = `https://${stage}.rhythia.com`;
|
|
8
|
+
}
|
|
9
|
+
export function setEndpoint(value: string) {
|
|
10
|
+
endpoint = value;
|
|
8
11
|
}
|
|
9
12
|
export function handleApi<
|
|
10
|
-
T extends { url: string; input: z.ZodObject<any>; output: z.
|
|
13
|
+
T extends { url: string; input: z.ZodObject<any>; output: z.ZodTypeAny }
|
|
11
14
|
>(apiSchema: T) {
|
|
12
15
|
profanity.whitelist.addWords(["willy"]);
|
|
13
16
|
return async (input: T["input"]["_type"]): Promise<T["output"]["_type"]> => {
|
|
14
|
-
const response = await fetch(
|
|
17
|
+
const response = await fetch(`${endpoint}${apiSchema.url}`, {
|
|
15
18
|
method: "POST",
|
|
16
19
|
body: JSON.stringify(input),
|
|
17
20
|
});
|
package/index.ts
CHANGED
|
@@ -392,18 +392,18 @@ export const executeAdminOperation = handleApi({url:"/api/executeAdminOperation"
|
|
|
392
392
|
// ./api/getAvatarUploadUrl.ts API
|
|
393
393
|
|
|
394
394
|
/*
|
|
395
|
-
export const Schema = {
|
|
396
|
-
input: z.strictObject({
|
|
397
|
-
session: z.string(),
|
|
398
|
-
contentLength: z.number(),
|
|
399
|
-
contentType: z.string(),
|
|
400
|
-
intrinsicToken: z.string(),
|
|
401
|
-
}),
|
|
402
|
-
output: z.strictObject({
|
|
403
|
-
error: z.string().optional(),
|
|
404
|
-
url: z.string().optional(),
|
|
405
|
-
objectKey: z.string().optional(),
|
|
406
|
-
}),
|
|
395
|
+
export const Schema = {
|
|
396
|
+
input: z.strictObject({
|
|
397
|
+
session: z.string(),
|
|
398
|
+
contentLength: z.number(),
|
|
399
|
+
contentType: z.string(),
|
|
400
|
+
intrinsicToken: z.string(),
|
|
401
|
+
}),
|
|
402
|
+
output: z.strictObject({
|
|
403
|
+
error: z.string().optional(),
|
|
404
|
+
url: z.string().optional(),
|
|
405
|
+
objectKey: z.string().optional(),
|
|
406
|
+
}),
|
|
407
407
|
};*/
|
|
408
408
|
import { Schema as GetAvatarUploadUrl } from "./api/getAvatarUploadUrl"
|
|
409
409
|
export { Schema as SchemaGetAvatarUploadUrl } from "./api/getAvatarUploadUrl"
|
|
@@ -541,6 +541,7 @@ export const Schema = {
|
|
|
541
541
|
description: z.string().nullable().optional(),
|
|
542
542
|
tags: z.string().nullable().optional(),
|
|
543
543
|
videoUrl: z.string().nullable().optional(),
|
|
544
|
+
mapHash: z.string().nullable().optional(),
|
|
544
545
|
vetos: z
|
|
545
546
|
.array(
|
|
546
547
|
z.object({
|
|
@@ -613,6 +614,7 @@ export const Schema = {
|
|
|
613
614
|
qualified: z.boolean().nullable().optional(),
|
|
614
615
|
qualifiedAt: z.string().nullable().optional(),
|
|
615
616
|
videoUrl: z.string().nullable(),
|
|
617
|
+
mapHash: z.string().nullable().optional(),
|
|
616
618
|
vetos: z
|
|
617
619
|
.array(
|
|
618
620
|
z.object({
|
|
@@ -636,50 +638,51 @@ export const getBeatmapPageById = handleApi({url:"/api/getBeatmapPageById",...Ge
|
|
|
636
638
|
// ./api/getBeatmaps.ts API
|
|
637
639
|
|
|
638
640
|
/*
|
|
639
|
-
export const Schema = {
|
|
640
|
-
input: z.strictObject({
|
|
641
|
-
session: z.string(),
|
|
642
|
-
textFilter: z.string().optional(),
|
|
643
|
-
authorFilter: z.string().optional(),
|
|
644
|
-
tagsFilter: z.string().optional(),
|
|
645
|
-
page: z.number().default(1),
|
|
646
|
-
maxStars: z.number().optional(),
|
|
647
|
-
minLength: z.number().optional(),
|
|
648
|
-
maxLength: z.number().optional(),
|
|
649
|
-
minStars: z.number().optional(),
|
|
650
|
-
creator: z.number().optional(),
|
|
651
|
-
status: z.string().optional(),
|
|
652
|
-
}),
|
|
653
|
-
output: z.object({
|
|
654
|
-
error: z.string().optional(),
|
|
655
|
-
total: z.number(),
|
|
656
|
-
viewPerPage: z.number(),
|
|
657
|
-
currentPage: z.number(),
|
|
658
|
-
beatmaps: z
|
|
659
|
-
.array(
|
|
660
|
-
z.object({
|
|
661
|
-
id: z.number(),
|
|
662
|
-
playcount: z.number().nullable().optional(),
|
|
663
|
-
created_at: z.string().nullable().optional(),
|
|
664
|
-
difficulty: z.number().nullable().optional(),
|
|
665
|
-
noteCount: z.number().nullable().optional(),
|
|
666
|
-
length: z.number().nullable().optional(),
|
|
667
|
-
title: z.string().nullable().optional(),
|
|
668
|
-
ranked: z.boolean().nullable().optional(),
|
|
669
|
-
beatmapFile: z.string().nullable().optional(),
|
|
670
|
-
image: z.string().nullable().optional(),
|
|
671
|
-
starRating: z.number().nullable().optional(),
|
|
672
|
-
owner: z.number().nullable().optional(),
|
|
673
|
-
ownerUsername: z.string().nullable().optional(),
|
|
674
|
-
ownerAvatar: z.string().nullable().optional(),
|
|
675
|
-
status: z.string().nullable().optional(),
|
|
676
|
-
qualified: z.boolean().nullable().optional(),
|
|
677
|
-
tags: z.string().nullable().optional(),
|
|
678
|
-
videoUrl: z.string().nullable().optional(),
|
|
679
|
-
|
|
680
|
-
|
|
681
|
-
|
|
682
|
-
|
|
641
|
+
export const Schema = {
|
|
642
|
+
input: z.strictObject({
|
|
643
|
+
session: z.string(),
|
|
644
|
+
textFilter: z.string().optional(),
|
|
645
|
+
authorFilter: z.string().optional(),
|
|
646
|
+
tagsFilter: z.string().optional(),
|
|
647
|
+
page: z.number().default(1),
|
|
648
|
+
maxStars: z.number().optional(),
|
|
649
|
+
minLength: z.number().optional(),
|
|
650
|
+
maxLength: z.number().optional(),
|
|
651
|
+
minStars: z.number().optional(),
|
|
652
|
+
creator: z.number().optional(),
|
|
653
|
+
status: z.string().optional(),
|
|
654
|
+
}),
|
|
655
|
+
output: z.object({
|
|
656
|
+
error: z.string().optional(),
|
|
657
|
+
total: z.number(),
|
|
658
|
+
viewPerPage: z.number(),
|
|
659
|
+
currentPage: z.number(),
|
|
660
|
+
beatmaps: z
|
|
661
|
+
.array(
|
|
662
|
+
z.object({
|
|
663
|
+
id: z.number(),
|
|
664
|
+
playcount: z.number().nullable().optional(),
|
|
665
|
+
created_at: z.string().nullable().optional(),
|
|
666
|
+
difficulty: z.number().nullable().optional(),
|
|
667
|
+
noteCount: z.number().nullable().optional(),
|
|
668
|
+
length: z.number().nullable().optional(),
|
|
669
|
+
title: z.string().nullable().optional(),
|
|
670
|
+
ranked: z.boolean().nullable().optional(),
|
|
671
|
+
beatmapFile: z.string().nullable().optional(),
|
|
672
|
+
image: z.string().nullable().optional(),
|
|
673
|
+
starRating: z.number().nullable().optional(),
|
|
674
|
+
owner: z.number().nullable().optional(),
|
|
675
|
+
ownerUsername: z.string().nullable().optional(),
|
|
676
|
+
ownerAvatar: z.string().nullable().optional(),
|
|
677
|
+
status: z.string().nullable().optional(),
|
|
678
|
+
qualified: z.boolean().nullable().optional(),
|
|
679
|
+
tags: z.string().nullable().optional(),
|
|
680
|
+
videoUrl: z.string().nullable().optional(),
|
|
681
|
+
mapHash: z.string().nullable().optional(),
|
|
682
|
+
})
|
|
683
|
+
)
|
|
684
|
+
.optional(),
|
|
685
|
+
}),
|
|
683
686
|
};*/
|
|
684
687
|
import { Schema as GetBeatmaps } from "./api/getBeatmaps"
|
|
685
688
|
export { Schema as SchemaGetBeatmaps } from "./api/getBeatmaps"
|
|
@@ -706,6 +709,28 @@ import { Schema as GetBeatmapStarRating } from "./api/getBeatmapStarRating"
|
|
|
706
709
|
export { Schema as SchemaGetBeatmapStarRating } from "./api/getBeatmapStarRating"
|
|
707
710
|
export const getBeatmapStarRating = handleApi({url:"/api/getBeatmapStarRating",...GetBeatmapStarRating})
|
|
708
711
|
|
|
712
|
+
// ./api/getChangelog.ts API
|
|
713
|
+
|
|
714
|
+
/*
|
|
715
|
+
export const Schema = {
|
|
716
|
+
input: z.strictObject({
|
|
717
|
+
type: changelogType,
|
|
718
|
+
skip: z.number().default(0),
|
|
719
|
+
limit: z.number().default(10),
|
|
720
|
+
}),
|
|
721
|
+
output: z.array(
|
|
722
|
+
z.object({
|
|
723
|
+
id: z.number(),
|
|
724
|
+
type: z.string(),
|
|
725
|
+
date: z.string(),
|
|
726
|
+
markdown: z.string(),
|
|
727
|
+
})
|
|
728
|
+
),
|
|
729
|
+
};*/
|
|
730
|
+
import { Schema as GetChangelog } from "./api/getChangelog"
|
|
731
|
+
export { Schema as SchemaGetChangelog } from "./api/getChangelog"
|
|
732
|
+
export const getChangelog = handleApi({url:"/api/getChangelog",...GetChangelog})
|
|
733
|
+
|
|
709
734
|
// ./api/getClan.ts API
|
|
710
735
|
|
|
711
736
|
/*
|
|
@@ -783,19 +808,22 @@ export const Schema = {
|
|
|
783
808
|
input: z.strictObject({
|
|
784
809
|
session: z.string(),
|
|
785
810
|
collection: z.number(),
|
|
811
|
+
page: z.number().optional().default(1),
|
|
812
|
+
itemsPerPage: z.number().optional().default(30),
|
|
786
813
|
}),
|
|
787
814
|
output: z.object({
|
|
788
|
-
collection: z.object({
|
|
789
|
-
title: z.string(),
|
|
790
|
-
description: z.string(),
|
|
791
|
-
owner: z.object({
|
|
792
|
-
id: z.number(),
|
|
793
|
-
username: z.string(),
|
|
794
|
-
avatar_url: z.string().nullable(),
|
|
795
|
-
}),
|
|
796
|
-
isList: z.boolean(),
|
|
797
|
-
|
|
798
|
-
|
|
815
|
+
collection: z.object({
|
|
816
|
+
title: z.string(),
|
|
817
|
+
description: z.string(),
|
|
818
|
+
owner: z.object({
|
|
819
|
+
id: z.number(),
|
|
820
|
+
username: z.string(),
|
|
821
|
+
avatar_url: z.string().nullable(),
|
|
822
|
+
}),
|
|
823
|
+
isList: z.boolean(),
|
|
824
|
+
beatmapCount: z.number(),
|
|
825
|
+
beatmaps: z.array(
|
|
826
|
+
z.object({
|
|
799
827
|
id: z.number(),
|
|
800
828
|
playcount: z.number().nullable().optional(),
|
|
801
829
|
created_at: z.string().nullable().optional(),
|
|
@@ -813,6 +841,7 @@ export const Schema = {
|
|
|
813
841
|
})
|
|
814
842
|
),
|
|
815
843
|
}),
|
|
844
|
+
totalPages: z.number(),
|
|
816
845
|
error: z.string().optional(),
|
|
817
846
|
}),
|
|
818
847
|
};*/
|
|
@@ -939,19 +968,19 @@ export const getLeaderboard = handleApi({url:"/api/getLeaderboard",...GetLeaderb
|
|
|
939
968
|
// ./api/getMapUploadUrl.ts API
|
|
940
969
|
|
|
941
970
|
/*
|
|
942
|
-
export const Schema = {
|
|
943
|
-
input: z.strictObject({
|
|
944
|
-
mapName: z.string().optional(),
|
|
945
|
-
session: z.string(),
|
|
946
|
-
contentLength: z.number(),
|
|
947
|
-
contentType: z.string(),
|
|
948
|
-
intrinsicToken: z.string(),
|
|
949
|
-
}),
|
|
950
|
-
output: z.strictObject({
|
|
951
|
-
error: z.string().optional(),
|
|
952
|
-
url: z.string().optional(),
|
|
953
|
-
objectKey: z.string().optional(),
|
|
954
|
-
}),
|
|
971
|
+
export const Schema = {
|
|
972
|
+
input: z.strictObject({
|
|
973
|
+
mapName: z.string().optional(),
|
|
974
|
+
session: z.string(),
|
|
975
|
+
contentLength: z.number(),
|
|
976
|
+
contentType: z.string(),
|
|
977
|
+
intrinsicToken: z.string(),
|
|
978
|
+
}),
|
|
979
|
+
output: z.strictObject({
|
|
980
|
+
error: z.string().optional(),
|
|
981
|
+
url: z.string().optional(),
|
|
982
|
+
objectKey: z.string().optional(),
|
|
983
|
+
}),
|
|
955
984
|
};*/
|
|
956
985
|
import { Schema as GetMapUploadUrl } from "./api/getMapUploadUrl"
|
|
957
986
|
export { Schema as SchemaGetMapUploadUrl } from "./api/getMapUploadUrl"
|
|
@@ -1000,56 +1029,56 @@ export const getPassToken = handleApi({url:"/api/getPassToken",...GetPassToken})
|
|
|
1000
1029
|
// ./api/getProfile.ts API
|
|
1001
1030
|
|
|
1002
1031
|
/*
|
|
1003
|
-
export const Schema = {
|
|
1004
|
-
input: z.strictObject({
|
|
1005
|
-
session: z.string(),
|
|
1006
|
-
id: z.number().nullable().optional(),
|
|
1007
|
-
}),
|
|
1008
|
-
output: z.object({
|
|
1009
|
-
error: z.string().optional(),
|
|
1010
|
-
user: z
|
|
1011
|
-
.object({
|
|
1012
|
-
about_me: z.string().nullable(),
|
|
1013
|
-
avatar_url: z.string().nullable(),
|
|
1014
|
-
profile_image: z.string().nullable(),
|
|
1015
|
-
badges: z.any().nullable(),
|
|
1016
|
-
created_at: z.number().nullable(),
|
|
1017
|
-
flag: z.string().nullable(),
|
|
1018
|
-
id: z.number(),
|
|
1019
|
-
uid: z.string().nullable(),
|
|
1020
|
-
ban: z.string().nullable(),
|
|
1021
|
-
username: z.string().nullable(),
|
|
1022
|
-
verified: z.boolean().nullable(),
|
|
1023
|
-
verificationDeadline: z.number().nullable(),
|
|
1024
|
-
play_count: z.number().nullable(),
|
|
1025
|
-
skill_points: z.number().nullable(),
|
|
1026
|
-
squares_hit: z.number().nullable(),
|
|
1027
|
-
total_score: z.number().nullable(),
|
|
1028
|
-
position: z.number().nullable(),
|
|
1029
|
-
country_position: z.number().nullable(),
|
|
1030
|
-
activity_status: z.enum(["active", "inactive"]),
|
|
1031
|
-
is_online: z.boolean(),
|
|
1032
|
-
last_active_timestamp: z.number().nullable(),
|
|
1033
|
-
friend_count: z.number(),
|
|
1034
|
-
friend_state: friendStateSchema,
|
|
1035
|
-
can_change_flag: z.boolean(),
|
|
1036
|
-
next_username_change_at: z.string().nullable(),
|
|
1037
|
-
previous_usernames: z.array(
|
|
1038
|
-
z.object({
|
|
1039
|
-
username: z.string(),
|
|
1040
|
-
changed_at: z.string(),
|
|
1041
|
-
})
|
|
1042
|
-
),
|
|
1043
|
-
clans: z
|
|
1044
|
-
.object({
|
|
1045
|
-
id: z.number(),
|
|
1046
|
-
acronym: z.string(),
|
|
1047
|
-
})
|
|
1048
|
-
.optional()
|
|
1049
|
-
.nullable(),
|
|
1050
|
-
})
|
|
1051
|
-
.optional(),
|
|
1052
|
-
}),
|
|
1032
|
+
export const Schema = {
|
|
1033
|
+
input: z.strictObject({
|
|
1034
|
+
session: z.string(),
|
|
1035
|
+
id: z.number().nullable().optional(),
|
|
1036
|
+
}),
|
|
1037
|
+
output: z.object({
|
|
1038
|
+
error: z.string().optional(),
|
|
1039
|
+
user: z
|
|
1040
|
+
.object({
|
|
1041
|
+
about_me: z.string().nullable(),
|
|
1042
|
+
avatar_url: z.string().nullable(),
|
|
1043
|
+
profile_image: z.string().nullable(),
|
|
1044
|
+
badges: z.any().nullable(),
|
|
1045
|
+
created_at: z.number().nullable(),
|
|
1046
|
+
flag: z.string().nullable(),
|
|
1047
|
+
id: z.number(),
|
|
1048
|
+
uid: z.string().nullable(),
|
|
1049
|
+
ban: z.string().nullable(),
|
|
1050
|
+
username: z.string().nullable(),
|
|
1051
|
+
verified: z.boolean().nullable(),
|
|
1052
|
+
verificationDeadline: z.number().nullable(),
|
|
1053
|
+
play_count: z.number().nullable(),
|
|
1054
|
+
skill_points: z.number().nullable(),
|
|
1055
|
+
squares_hit: z.number().nullable(),
|
|
1056
|
+
total_score: z.number().nullable(),
|
|
1057
|
+
position: z.number().nullable(),
|
|
1058
|
+
country_position: z.number().nullable(),
|
|
1059
|
+
activity_status: z.enum(["active", "inactive"]),
|
|
1060
|
+
is_online: z.boolean(),
|
|
1061
|
+
last_active_timestamp: z.number().nullable(),
|
|
1062
|
+
friend_count: z.number(),
|
|
1063
|
+
friend_state: friendStateSchema,
|
|
1064
|
+
can_change_flag: z.boolean(),
|
|
1065
|
+
next_username_change_at: z.string().nullable(),
|
|
1066
|
+
previous_usernames: z.array(
|
|
1067
|
+
z.object({
|
|
1068
|
+
username: z.string(),
|
|
1069
|
+
changed_at: z.string(),
|
|
1070
|
+
})
|
|
1071
|
+
),
|
|
1072
|
+
clans: z
|
|
1073
|
+
.object({
|
|
1074
|
+
id: z.number(),
|
|
1075
|
+
acronym: z.string(),
|
|
1076
|
+
})
|
|
1077
|
+
.optional()
|
|
1078
|
+
.nullable(),
|
|
1079
|
+
})
|
|
1080
|
+
.optional(),
|
|
1081
|
+
}),
|
|
1053
1082
|
};*/
|
|
1054
1083
|
import { Schema as GetProfile } from "./api/getProfile"
|
|
1055
1084
|
export { Schema as SchemaGetProfile } from "./api/getProfile"
|
|
@@ -1161,6 +1190,7 @@ export const Schema = {
|
|
|
1161
1190
|
username: z.string().optional().nullable(),
|
|
1162
1191
|
speed: z.number().optional().nullable(),
|
|
1163
1192
|
spin: z.boolean().optional().nullable(),
|
|
1193
|
+
replay_url: z.string().optional().nullable(),
|
|
1164
1194
|
})
|
|
1165
1195
|
.optional(),
|
|
1166
1196
|
}),
|
|
@@ -1321,18 +1351,18 @@ export const getVerified = handleApi({url:"/api/getVerified",...GetVerified})
|
|
|
1321
1351
|
// ./api/getVideoUploadUrl.ts API
|
|
1322
1352
|
|
|
1323
1353
|
/*
|
|
1324
|
-
export const Schema = {
|
|
1325
|
-
input: z.strictObject({
|
|
1326
|
-
session: z.string(),
|
|
1327
|
-
contentLength: z.number(),
|
|
1328
|
-
contentType: z.string(),
|
|
1329
|
-
intrinsicToken: z.string(),
|
|
1330
|
-
}),
|
|
1331
|
-
output: z.strictObject({
|
|
1332
|
-
error: z.string().optional(),
|
|
1333
|
-
url: z.string().optional(),
|
|
1334
|
-
objectKey: z.string().optional(),
|
|
1335
|
-
}),
|
|
1354
|
+
export const Schema = {
|
|
1355
|
+
input: z.strictObject({
|
|
1356
|
+
session: z.string(),
|
|
1357
|
+
contentLength: z.number(),
|
|
1358
|
+
contentType: z.string(),
|
|
1359
|
+
intrinsicToken: z.string(),
|
|
1360
|
+
}),
|
|
1361
|
+
output: z.strictObject({
|
|
1362
|
+
error: z.string().optional(),
|
|
1363
|
+
url: z.string().optional(),
|
|
1364
|
+
objectKey: z.string().optional(),
|
|
1365
|
+
}),
|
|
1336
1366
|
};*/
|
|
1337
1367
|
import { Schema as GetVideoUploadUrl } from "./api/getVideoUploadUrl"
|
|
1338
1368
|
export { Schema as SchemaGetVideoUploadUrl } from "./api/getVideoUploadUrl"
|
|
@@ -1479,26 +1509,27 @@ export const submitScore = handleApi({url:"/api/submitScore",...SubmitScore})
|
|
|
1479
1509
|
// ./api/submitScoreInternal.ts API
|
|
1480
1510
|
|
|
1481
1511
|
/*
|
|
1482
|
-
export const Schema = {
|
|
1483
|
-
input: z.strictObject({
|
|
1484
|
-
session: z.string(),
|
|
1485
|
-
secret: z.string(),
|
|
1486
|
-
token: z.string(),
|
|
1487
|
-
data: z.strictObject({
|
|
1488
|
-
|
|
1489
|
-
|
|
1490
|
-
|
|
1491
|
-
|
|
1492
|
-
|
|
1493
|
-
|
|
1494
|
-
|
|
1495
|
-
|
|
1496
|
-
|
|
1497
|
-
|
|
1498
|
-
|
|
1499
|
-
|
|
1500
|
-
|
|
1501
|
-
|
|
1512
|
+
export const Schema = {
|
|
1513
|
+
input: z.strictObject({
|
|
1514
|
+
session: z.string(),
|
|
1515
|
+
secret: z.string(),
|
|
1516
|
+
token: z.string(),
|
|
1517
|
+
data: z.strictObject({
|
|
1518
|
+
beatmapHash: z.string().optional().nullable(),
|
|
1519
|
+
onlineMapId: z.number(),
|
|
1520
|
+
misses: z.number(),
|
|
1521
|
+
hits: z.number(),
|
|
1522
|
+
speed: z.number(),
|
|
1523
|
+
mods: z.array(z.string()),
|
|
1524
|
+
spin: z.boolean(),
|
|
1525
|
+
replayBytes: z.string().nullable().optional(),
|
|
1526
|
+
pauses: z.number().nullable().optional(),
|
|
1527
|
+
failTime: z.number().nullable().optional(),
|
|
1528
|
+
}),
|
|
1529
|
+
}),
|
|
1530
|
+
output: z.object({
|
|
1531
|
+
error: z.string().optional(),
|
|
1532
|
+
}),
|
|
1502
1533
|
};*/
|
|
1503
1534
|
import { Schema as SubmitScoreInternal } from "./api/submitScoreInternal"
|
|
1504
1535
|
export { Schema as SchemaSubmitScoreInternal } from "./api/submitScoreInternal"
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "rhythia-api",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "244.0.0",
|
|
4
4
|
"main": "index.ts",
|
|
5
5
|
"author": "online-contributors-cunev",
|
|
6
6
|
"scripts": {
|
|
@@ -10,6 +10,8 @@
|
|
|
10
10
|
"test": "tsx ./scripts/test.ts",
|
|
11
11
|
"cache:clear-user-scores": "bun run scripts/clear-user-score-cache.ts",
|
|
12
12
|
"db:optimize-user-scores": "bun run scripts/optimize-user-scores-indexes.ts",
|
|
13
|
+
"db:add-beatmap-page-map-hash": "node --experimental-transform-types scripts/add-beatmap-page-map-hash.ts",
|
|
14
|
+
"db:backfill-beatmap-page-map-hashes": "node --experimental-transform-types scripts/backfill-beatmap-page-map-hashes.ts",
|
|
13
15
|
"db:create-profile-flags": "node scripts/create-profile-flags-table.ts",
|
|
14
16
|
"db:create-profile-friends": "node scripts/create-profile-friends-table.ts",
|
|
15
17
|
"db:create-profile-reports": "node scripts/create-profile-reports-table.ts",
|
|
@@ -17,7 +19,8 @@
|
|
|
17
19
|
"query-push": "bun run scripts/deploy-queries.ts",
|
|
18
20
|
"queries:pull": "bun run scripts/pull-queries.ts",
|
|
19
21
|
"queries:deploy": "bun run scripts/deploy-queries.ts",
|
|
20
|
-
"sync": "npx supabase gen types typescript --project-id \"pfkajngbllcbdzoylrvp\" --schema public > types/database.ts"
|
|
22
|
+
"sync": "npx supabase gen types typescript --project-id \"pfkajngbllcbdzoylrvp\" --schema public > types/database.ts",
|
|
23
|
+
"sync-dev": "npx supabase gen types typescript --project-id \"gcxlgiajvbpbimrfqbwp\" --schema public > types/database.ts"
|
|
21
24
|
},
|
|
22
25
|
"license": "MIT",
|
|
23
26
|
"dependencies": {
|
|
@@ -28,7 +31,7 @@
|
|
|
28
31
|
"@supabase/supabase-js": "^2.45.1",
|
|
29
32
|
"@types/bun": "^1.1.6",
|
|
30
33
|
"@types/lodash": "^4.17.7",
|
|
31
|
-
"@types/node": "^
|
|
34
|
+
"@types/node": "^25.6.0",
|
|
32
35
|
"@types/pg": "^8.15.5",
|
|
33
36
|
"@types/validator": "^13.12.2",
|
|
34
37
|
"bad-words": "^4.0.0",
|
|
@@ -42,6 +45,7 @@
|
|
|
42
45
|
"osu-classes": "^3.1.0",
|
|
43
46
|
"osu-parsers": "^4.1.7",
|
|
44
47
|
"osu-standard-stable": "^5.0.0",
|
|
48
|
+
"pako": "^2.1.0",
|
|
45
49
|
"pg": "^8.18.0",
|
|
46
50
|
"redis": "^5.10.0",
|
|
47
51
|
"remote-cloudflare-kv": "^1.0.1",
|
|
@@ -1,39 +1,42 @@
|
|
|
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
|
|
28
|
-
DELETE FROM public.
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
--
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
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 user HWID records
|
|
28
|
+
DELETE FROM public.user_hwids WHERE id = user_id;
|
|
29
|
+
|
|
30
|
+
-- Delete profile activity
|
|
31
|
+
DELETE FROM public."profileActivities"
|
|
32
|
+
WHERE uid = (SELECT uid FROM public.profiles WHERE id = user_id);
|
|
33
|
+
|
|
34
|
+
-- Finally, delete the profile
|
|
35
|
+
DELETE FROM public.profiles WHERE id = user_id;
|
|
36
|
+
|
|
37
|
+
-- Check if deletion was successful
|
|
38
|
+
success := NOT EXISTS (SELECT 1 FROM public.profiles WHERE id = user_id);
|
|
39
|
+
|
|
40
|
+
RETURN success;
|
|
41
|
+
END;
|
|
42
|
+
$function$
|
|
@@ -5,9 +5,12 @@ CREATE OR REPLACE FUNCTION public.admin_remove_all_scores(user_id integer)
|
|
|
5
5
|
AS $function$
|
|
6
6
|
DECLARE
|
|
7
7
|
deleted_count INTEGER;
|
|
8
|
-
BEGIN
|
|
9
|
-
|
|
10
|
-
|
|
8
|
+
BEGIN
|
|
9
|
+
DELETE FROM public.leaderboard_map_user
|
|
10
|
+
WHERE "userId" = user_id;
|
|
11
|
+
|
|
12
|
+
-- Delete all scores for this user and count them
|
|
13
|
+
WITH deleted AS (
|
|
11
14
|
DELETE FROM public.scores
|
|
12
15
|
WHERE "userId" = user_id
|
|
13
16
|
RETURNING *
|