rhythia-api 146.0.0 → 147.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 (2) hide show
  1. package/index.ts +24 -1610
  2. package/package.json +1 -1
package/index.ts CHANGED
@@ -11,68 +11,7 @@ export const Schema = {
11
11
  output: z.object({
12
12
  error: z.string().optional(),
13
13
  }),
14
- };
15
-
16
- export async function POST(request: Request) {
17
- return protectedApi({
18
- request,
19
- schema: Schema,
20
- authorization: validUser,
21
- activity: handler,
22
- });
23
- }
24
-
25
- export async function handler(data: (typeof Schema)["input"]["_type"]) {
26
- const user = (await supabase.auth.getUser(data.session)).data.user!;
27
- let { data: queryUserData, error: userError } = await supabase
28
- .from("profiles")
29
- .select("*")
30
- .eq("uid", user.id)
31
- .single();
32
-
33
- if (!queryUserData) {
34
- return NextResponse.json({ error: "Can't find user" });
35
- }
36
-
37
- const tags = (queryUserData?.badges || []) as string[];
38
-
39
- if (!tags.includes("MMT")) {
40
- return NextResponse.json({ error: "Only MMTs can approve maps!" });
41
- }
42
-
43
- const { data: mapData, error } = await supabase
44
- .from("beatmapPages")
45
- .select("id,nominations,owner")
46
- .eq("id", data.mapId)
47
- .single();
48
-
49
- if (!mapData) {
50
- return NextResponse.json({ error: "Bad map" });
51
- }
52
-
53
- if (mapData.owner == queryUserData.id) {
54
- return NextResponse.json({ error: "Can't approve own map" });
55
- }
56
-
57
- if ((mapData.nominations as number[])!.length < 2) {
58
- return NextResponse.json({
59
- error: "Maps can get approved only if they have 2 nominations",
60
- });
61
- }
62
-
63
- if ((mapData.nominations as number[]).includes(queryUserData.id)) {
64
- return NextResponse.json({
65
- error: "Can't nominate and approve",
66
- });
67
- }
68
-
69
- await supabase.from("beatmapPages").upsert({
70
- id: data.mapId,
71
- status: "RANKED",
72
- });
73
-
74
- return NextResponse.json({});
75
- }
14
+ */
76
15
  import { Schema as ApproveMap } from "./api/approveMap"
77
16
  export { Schema as SchemaApproveMap } from "./api/approveMap"
78
17
  export const approveMap = handleApi({url:"/api/approveMap",...ApproveMap})
@@ -90,110 +29,7 @@ export const Schema = {
90
29
  hash: z.string().optional(),
91
30
  error: z.string().optional(),
92
31
  }),
93
- };
94
-
95
- export async function POST(request: Request): Promise<NextResponse> {
96
- return protectedApi({
97
- request,
98
- schema: Schema,
99
- authorization: validUser,
100
- activity: handler,
101
- });
102
- }
103
-
104
- export async function handler({
105
- url,
106
- session,
107
- updateFlag,
108
- }: (typeof Schema)["input"]["_type"]): Promise<
109
- NextResponse<(typeof Schema)["output"]["_type"]>
110
- > {
111
- if (!url.startsWith(`https://static.rhythia.com/`))
112
- return NextResponse.json({ error: "Invalid url" });
113
-
114
- const request = await fetch(url);
115
- const bytes = await request.arrayBuffer();
116
- const parser = new SSPMParser(Buffer.from(bytes));
117
-
118
- const parsedData = parser.parse();
119
- const digested = parsedData.strings.mapID;
120
-
121
- const user = (await supabase.auth.getUser(session)).data.user!;
122
- let { data: userData, error: userError } = await supabase
123
- .from("profiles")
124
- .select("*")
125
- .eq("uid", user.id)
126
- .single();
127
-
128
- if (!userData) {
129
- return NextResponse.json({ error: "Bad user" });
130
- }
131
-
132
- if (
133
- userData.ban == "excluded" ||
134
- userData.ban == "restricted" ||
135
- userData.ban == "silenced"
136
- ) {
137
- return NextResponse.json(
138
- {
139
- error:
140
- "Silenced, restricted or excluded players can't update their profile.",
141
- },
142
- { status: 404 }
143
- );
144
- }
145
-
146
- let { data: beatmapPage, error: errorlast } = await supabase
147
- .from("beatmapPages")
148
- .select(`*`)
149
- .eq("latestBeatmapHash", digested)
150
- .single();
151
-
152
- if (beatmapPage) {
153
- if (!updateFlag) {
154
- return NextResponse.json({ error: "Already Exists" });
155
- } else if (beatmapPage.owner !== userData.id) {
156
- return NextResponse.json({ error: "Already Exists" });
157
- }
158
- }
159
-
160
- const imgkey = `beatmap-img-${Date.now()}-${digested}`;
161
-
162
- let buffer = Buffer.from([]);
163
- try {
164
- buffer = await require("sharp")(parsedData.cover)
165
- .resize(250)
166
- .jpeg({ mozjpeg: true })
167
- .toBuffer();
168
- } catch (error) {}
169
-
170
- const command = new PutObjectCommand({
171
- Bucket: "rhthia-avatars",
172
- Key: imgkey,
173
- Body: buffer,
174
- ContentType: "image/jpeg",
175
- });
176
-
177
- await s3Client.send(command);
178
- const markers = parsedData.markers.sort((a, b) => a.position - b.position);
179
-
180
- const upserted = await supabase.from("beatmaps").upsert({
181
- beatmapHash: digested,
182
- title: parsedData.strings.mapName,
183
- playcount: 0,
184
- difficulty: parsedData.metadata.difficulty,
185
- noteCount: parsedData.metadata.noteCount,
186
- length: markers[markers.length - 1].position,
187
- beatmapFile: url,
188
- image: `https://static.rhythia.com/${imgkey}`,
189
- starRating: rateMap(parsedData),
190
- });
191
-
192
- if (upserted.error?.message.length) {
193
- return NextResponse.json({ error: upserted.error.message });
194
- }
195
- return NextResponse.json({ hash: digested });
196
- }
32
+ */
197
33
  import { Schema as CreateBeatmap } from "./api/createBeatmap"
198
34
  export { Schema as SchemaCreateBeatmap } from "./api/createBeatmap"
199
35
  export const createBeatmap = handleApi({url:"/api/createBeatmap",...CreateBeatmap})
@@ -209,54 +45,7 @@ export const Schema = {
209
45
  error: z.string().optional(),
210
46
  id: z.number().optional(),
211
47
  }),
212
- };
213
-
214
- export async function POST(request: Request): Promise<NextResponse> {
215
- return protectedApi({
216
- request,
217
- schema: Schema,
218
- authorization: validUser,
219
- activity: handler,
220
- });
221
- }
222
-
223
- export async function handler({
224
- session,
225
- }: (typeof Schema)["input"]["_type"]): Promise<
226
- NextResponse<(typeof Schema)["output"]["_type"]>
227
- > {
228
- const user = (await supabase.auth.getUser(session)).data.user!;
229
- let { data: userData, error: userError } = await supabase
230
- .from("profiles")
231
- .select("*")
232
- .eq("uid", user.id)
233
- .single();
234
-
235
- if (!userData) return NextResponse.json({ error: "No user." });
236
-
237
- if (
238
- userData.ban == "excluded" ||
239
- userData.ban == "restricted" ||
240
- userData.ban == "silenced"
241
- ) {
242
- return NextResponse.json(
243
- {
244
- error:
245
- "Silenced, restricted or excluded players can't update their profile.",
246
- },
247
- { status: 404 }
248
- );
249
- }
250
-
251
- const upserted = await supabase
252
- .from("beatmapPages")
253
- .upsert({
254
- owner: userData.id,
255
- })
256
- .select("*")
257
- .single();
258
- return NextResponse.json({ id: upserted.data?.id });
259
- }
48
+ */
260
49
  import { Schema as CreateBeatmapPage } from "./api/createBeatmapPage"
261
50
  export { Schema as SchemaCreateBeatmapPage } from "./api/createBeatmapPage"
262
51
  export const createBeatmapPage = handleApi({url:"/api/createBeatmapPage",...CreateBeatmapPage})
@@ -272,62 +61,7 @@ export const Schema = {
272
61
  output: z.strictObject({
273
62
  error: z.string().optional(),
274
63
  }),
275
- };
276
-
277
- export async function POST(request: Request): Promise<NextResponse> {
278
- return protectedApi({
279
- request,
280
- schema: Schema,
281
- authorization: validUser,
282
- activity: handler,
283
- });
284
- }
285
-
286
- export async function handler({
287
- session,
288
- id,
289
- }: (typeof Schema)["input"]["_type"]): Promise<
290
- NextResponse<(typeof Schema)["output"]["_type"]>
291
- > {
292
- const user = (await supabase.auth.getUser(session)).data.user!;
293
- let { data: userData, error: userError } = await supabase
294
- .from("profiles")
295
- .select("*")
296
- .eq("uid", user.id)
297
- .single();
298
-
299
- let { data: pageData, error: pageError } = await supabase
300
- .from("beatmapPages")
301
- .select("*")
302
- .eq("id", id)
303
- .single();
304
-
305
- if (!pageData) return NextResponse.json({ error: "No beatmap." });
306
-
307
- let { data: beatmapData, error: bmPageError } = await supabase
308
- .from("beatmaps")
309
- .select("*")
310
- .eq("beatmapHash", pageData.latestBeatmapHash || "-1-1-1-1")
311
- .single();
312
-
313
- if (!userData) return NextResponse.json({ error: "No user." });
314
- if (!beatmapData) return NextResponse.json({ error: "No beatmap." });
315
-
316
- if (userData.id !== pageData.owner)
317
- return NextResponse.json({ error: "Non-authz user." });
318
-
319
- if (pageData.status !== "UNRANKED")
320
- return NextResponse.json({ error: "Only unranked maps can be updated" });
321
-
322
- await supabase.from("beatmapPageComments").delete().eq("beatmapPage", id);
323
- await supabase.from("beatmapPages").delete().eq("id", id);
324
- await supabase
325
- .from("beatmaps")
326
- .delete()
327
- .eq("beatmapHash", beatmapData.beatmapHash);
328
-
329
- return NextResponse.json({});
330
- }
64
+ */
331
65
  import { Schema as DeleteBeatmapPage } from "./api/deleteBeatmapPage"
332
66
  export { Schema as SchemaDeleteBeatmapPage } from "./api/deleteBeatmapPage"
333
67
  export const deleteBeatmapPage = handleApi({url:"/api/deleteBeatmapPage",...DeleteBeatmapPage})
@@ -345,80 +79,7 @@ export const Schema = {
345
79
  output: z.object({
346
80
  error: z.string().optional(),
347
81
  }),
348
- };
349
-
350
- export async function POST(request: Request): Promise<NextResponse> {
351
- return protectedApi({
352
- request,
353
- schema: Schema,
354
- authorization: validUser,
355
- activity: handler,
356
- });
357
- }
358
-
359
- export async function handler(
360
- data: (typeof Schema)["input"]["_type"]
361
- ): Promise<NextResponse<(typeof Schema)["output"]["_type"]>> {
362
- if (!data.data.about_me) {
363
- return NextResponse.json(
364
- {
365
- error: "Missing body.",
366
- },
367
- { status: 404 }
368
- );
369
- }
370
-
371
- if (data.data.about_me.length > 10000) {
372
- return NextResponse.json(
373
- {
374
- error: "Too long.",
375
- },
376
- { status: 404 }
377
- );
378
- }
379
-
380
- const user = (await supabase.auth.getUser(data.session)).data.user!;
381
- let userData: Database["public"]["Tables"]["profiles"]["Update"];
382
-
383
- // Find user's entry
384
- {
385
- let { data: queryUserData, error } = await supabase
386
- .from("profiles")
387
- .select("*")
388
- .eq("uid", user.id);
389
-
390
- if (!queryUserData?.length) {
391
- return NextResponse.json(
392
- {
393
- error: "User cannot be retrieved from session",
394
- },
395
- { status: 404 }
396
- );
397
- }
398
- userData = queryUserData[0];
399
- }
400
-
401
- const upsertPayload: Database["public"]["Tables"]["profiles"]["Update"] = {
402
- id: userData.id,
403
- about_me: data.data.about_me,
404
- };
405
-
406
- const upsertResult = await supabase
407
- .from("profiles")
408
- .upsert(upsertPayload)
409
- .select();
410
-
411
- if (upsertResult.error) {
412
- return NextResponse.json(
413
- {
414
- error: "Can't update..",
415
- },
416
- { status: 404 }
417
- );
418
- }
419
-
420
- return NextResponse.json({});
421
- }
82
+ */
422
83
  import { Schema as EditAboutMe } from "./api/editAboutMe"
423
84
  export { Schema as SchemaEditAboutMe } from "./api/editAboutMe"
424
85
  export const editAboutMe = handleApi({url:"/api/editAboutMe",...EditAboutMe})
@@ -437,96 +98,7 @@ export const Schema = {
437
98
  output: z.object({
438
99
  error: z.string().optional(),
439
100
  }),
440
- };
441
-
442
- export async function POST(request: Request): Promise<NextResponse> {
443
- return protectedApi({
444
- request,
445
- schema: Schema,
446
- authorization: validUser,
447
- activity: handler,
448
- });
449
- }
450
-
451
- export async function handler(
452
- data: (typeof Schema)["input"]["_type"]
453
- ): Promise<NextResponse<(typeof Schema)["output"]["_type"]>> {
454
- if (data.data.username !== undefined && data.data.username.length === 0) {
455
- return NextResponse.json(
456
- {
457
- error: "Username can't be empty",
458
- },
459
- { status: 404 }
460
- );
461
- }
462
-
463
- if (data.data.username && data.data.username.length > 20) {
464
- return NextResponse.json(
465
- {
466
- error: "Username too long.",
467
- },
468
- { status: 404 }
469
- );
470
- }
471
-
472
- const user = (await supabase.auth.getUser(data.session)).data.user!;
473
-
474
- let userData: Database["public"]["Tables"]["profiles"]["Update"];
475
-
476
- // Find user's entry
477
- {
478
- let { data: queryUserData, error } = await supabase
479
- .from("profiles")
480
- .select("*")
481
- .eq("uid", user.id);
482
-
483
- if (!queryUserData?.length) {
484
- return NextResponse.json(
485
- {
486
- error: "User cannot be retrieved from session",
487
- },
488
- { status: 404 }
489
- );
490
- }
491
- userData = queryUserData[0];
492
- }
493
-
494
- if (
495
- userData.ban == "excluded" ||
496
- userData.ban == "restricted" ||
497
- userData.ban == "silenced"
498
- ) {
499
- return NextResponse.json(
500
- {
501
- error:
502
- "Silenced, restricted or excluded players can't update their profile.",
503
- },
504
- { status: 404 }
505
- );
506
- }
507
-
508
- const upsertPayload: Database["public"]["Tables"]["profiles"]["Update"] = {
509
- id: userData.id,
510
- computedUsername: data.data.username?.toLowerCase(),
511
- ...data.data,
512
- };
513
-
514
- const upsertResult = await supabase
515
- .from("profiles")
516
- .upsert(upsertPayload)
517
- .select();
518
-
519
- if (upsertResult.error) {
520
- return NextResponse.json(
521
- {
522
- error: "Can't update, username might be used by someone else!",
523
- },
524
- { status: 404 }
525
- );
526
- }
527
-
528
- return NextResponse.json({});
529
- }
101
+ */
530
102
  import { Schema as EditProfile } from "./api/editProfile"
531
103
  export { Schema as SchemaEditProfile } from "./api/editProfile"
532
104
  export const editProfile = handleApi({url:"/api/editProfile",...EditProfile})
@@ -546,55 +118,7 @@ export const Schema = {
546
118
  url: z.string().optional(),
547
119
  objectKey: z.string().optional(),
548
120
  }),
549
- };
550
-
551
- export async function POST(request: Request): Promise<NextResponse> {
552
- return protectedApi({
553
- request,
554
- schema: Schema,
555
- authorization: validUser,
556
- activity: handler,
557
- });
558
- }
559
-
560
- export async function handler({
561
- session,
562
- contentLength,
563
- contentType,
564
- intrinsicToken,
565
- }: (typeof Schema)["input"]["_type"]): Promise<
566
- NextResponse<(typeof Schema)["output"]["_type"]>
567
- > {
568
- const user = (await supabase.auth.getUser(session)).data.user!;
569
-
570
- if (!validateIntrinsicToken(intrinsicToken)) {
571
- return NextResponse.json({
572
- error: "Invalid intrinsic token",
573
- });
574
- }
575
-
576
- if (contentLength > 5000000) {
577
- return NextResponse.json({
578
- error: "Max content length exceeded.",
579
- });
580
- }
581
-
582
- const key = `user-avatar-${Date.now()}-${user.id}`;
583
- const command = new PutObjectCommand({
584
- Bucket: "rhthia-avatars",
585
- Key: key,
586
- ContentLength: contentLength,
587
- ContentType: contentType,
588
- });
589
-
590
- const presigned = await getSignedUrl(s3Client, command, {
591
- expiresIn: 3600,
592
- });
593
- return NextResponse.json({
594
- url: presigned,
595
- objectKey: key,
596
- });
597
- }
121
+ */
598
122
  import { Schema as GetAvatarUploadUrl } from "./api/getAvatarUploadUrl"
599
123
  export { Schema as SchemaGetAvatarUploadUrl } from "./api/getAvatarUploadUrl"
600
124
  export const getAvatarUploadUrl = handleApi({url:"/api/getAvatarUploadUrl",...GetAvatarUploadUrl})
@@ -618,41 +142,7 @@ export const Schema = {
618
142
  )
619
143
  .optional(),
620
144
  }),
621
- };
622
-
623
- export async function POST(request: Request): Promise<NextResponse> {
624
- return protectedApi({
625
- request,
626
- schema: Schema,
627
- authorization: () => {},
628
- activity: handler,
629
- });
630
- }
631
-
632
- export async function handler(
633
- data: (typeof Schema)["input"]["_type"]
634
- ): Promise<NextResponse<(typeof Schema)["output"]["_type"]>> {
635
- const result = await getLeaderboard(data.badge);
636
- return NextResponse.json(result);
637
- }
638
-
639
- export async function getLeaderboard(badge: string) {
640
- let { data: queryData, error } = await supabase
641
- .from("profiles")
642
- .select("flag,id,username,badges");
643
-
644
- const users = queryData?.filter((e) =>
645
- ((e.badges || []) as string[]).includes(badge)
646
- );
647
-
648
- return {
649
- leaderboard: users?.map((user) => ({
650
- flag: user.flag,
651
- id: user.id,
652
- username: user.username,
653
- })),
654
- };
655
- }
145
+ */
656
146
  import { Schema as GetBadgedUsers } from "./api/getBadgedUsers"
657
147
  export { Schema as SchemaGetBadgedUsers } from "./api/getBadgedUsers"
658
148
  export const getBadgedUsers = handleApi({url:"/api/getBadgedUsers",...GetBadgedUsers})
@@ -680,38 +170,7 @@ export const Schema = {
680
170
  })
681
171
  ),
682
172
  }),
683
- };
684
-
685
- export async function POST(request: Request): Promise<NextResponse> {
686
- return protectedApi({
687
- request,
688
- schema: Schema,
689
- authorization: () => {},
690
- activity: handler,
691
- });
692
- }
693
-
694
- export async function handler({
695
- page,
696
- }: (typeof Schema)["input"]["_type"]): Promise<
697
- NextResponse<(typeof Schema)["output"]["_type"]>
698
- > {
699
- let { data: userData, error: userError } = await supabase
700
- .from("beatmapPageComments")
701
- .select(
702
- `
703
- *,
704
- profiles!inner(
705
- username,
706
- avatar_url,
707
- badges
708
- )
709
- `
710
- )
711
- .eq("beatmapPage", page);
712
-
713
- return NextResponse.json({ comments: userData! });
714
- }
173
+ */
715
174
  import { Schema as GetBeatmapComments } from "./api/getBeatmapComments"
716
175
  export { Schema as SchemaGetBeatmapComments } from "./api/getBeatmapComments"
717
176
  export const getBeatmapComments = handleApi({url:"/api/getBeatmapComments",...GetBeatmapComments})
@@ -747,70 +206,7 @@ export const Schema = {
747
206
  })
748
207
  .optional(),
749
208
  }),
750
- };
751
-
752
- export async function POST(request: Request): Promise<NextResponse> {
753
- return protectedApi({
754
- request,
755
- schema: Schema,
756
- authorization: () => {},
757
- activity: handler,
758
- });
759
- }
760
-
761
- export async function handler(
762
- data: (typeof Schema)["input"]["_type"],
763
- req: Request
764
- ): Promise<NextResponse<(typeof Schema)["output"]["_type"]>> {
765
- let { data: beatmapPage, error: errorlast } = await supabase
766
- .from("beatmapPages")
767
- .select(
768
- `
769
- *,
770
- beatmaps (
771
- created_at,
772
- playcount,
773
- length,
774
- ranked,
775
- beatmapFile,
776
- image,
777
- starRating,
778
- difficulty,
779
- noteCount,
780
- title
781
- ),
782
- profiles (
783
- username,
784
- avatar_url
785
- )
786
- `
787
- )
788
- .eq("id", data.id)
789
- .single();
790
-
791
- if (!beatmapPage) return NextResponse.json({});
792
-
793
- return NextResponse.json({
794
- beatmap: {
795
- playcount: beatmapPage.beatmaps?.playcount,
796
- created_at: beatmapPage.created_at,
797
- difficulty: beatmapPage.beatmaps?.difficulty,
798
- noteCount: beatmapPage.beatmaps?.noteCount,
799
- length: beatmapPage.beatmaps?.length,
800
- title: beatmapPage.beatmaps?.title,
801
- ranked: beatmapPage.beatmaps?.ranked,
802
- beatmapFile: beatmapPage.beatmaps?.beatmapFile,
803
- image: beatmapPage.beatmaps?.image,
804
- starRating: beatmapPage.beatmaps?.starRating,
805
- owner: beatmapPage.owner,
806
- ownerUsername: beatmapPage.profiles?.username,
807
- ownerAvatar: beatmapPage.profiles?.avatar_url,
808
- id: beatmapPage.id,
809
- status: beatmapPage.status,
810
- nominations: beatmapPage.nominations as number[],
811
- },
812
- });
813
- }
209
+ */
814
210
  import { Schema as GetBeatmapPage } from "./api/getBeatmapPage"
815
211
  export { Schema as SchemaGetBeatmapPage } from "./api/getBeatmapPage"
816
212
  export const getBeatmapPage = handleApi({url:"/api/getBeatmapPage",...GetBeatmapPage})
@@ -846,70 +242,7 @@ export const Schema = {
846
242
  })
847
243
  .optional(),
848
244
  }),
849
- };
850
-
851
- export async function POST(request: Request): Promise<NextResponse> {
852
- return protectedApi({
853
- request,
854
- schema: Schema,
855
- authorization: () => {},
856
- activity: handler,
857
- });
858
- }
859
-
860
- export async function handler(
861
- data: (typeof Schema)["input"]["_type"],
862
- req: Request
863
- ): Promise<NextResponse<(typeof Schema)["output"]["_type"]>> {
864
- let { data: beatmapPage, error: errorlast } = await supabase
865
- .from("beatmapPages")
866
- .select(
867
- `
868
- *,
869
- beatmaps (
870
- created_at,
871
- playcount,
872
- length,
873
- ranked,
874
- beatmapFile,
875
- image,
876
- starRating,
877
- difficulty,
878
- noteCount,
879
- title
880
- ),
881
- profiles (
882
- username,
883
- avatar_url
884
- )
885
- `
886
- )
887
- .eq("latestBeatmapHash", data.mapId)
888
- .single();
889
-
890
- if (!beatmapPage) return NextResponse.json({});
891
-
892
- return NextResponse.json({
893
- beatmap: {
894
- playcount: beatmapPage.beatmaps?.playcount,
895
- created_at: beatmapPage.created_at,
896
- difficulty: beatmapPage.beatmaps?.difficulty,
897
- noteCount: beatmapPage.beatmaps?.noteCount,
898
- length: beatmapPage.beatmaps?.length,
899
- title: beatmapPage.beatmaps?.title,
900
- ranked: beatmapPage.beatmaps?.ranked,
901
- beatmapFile: beatmapPage.beatmaps?.beatmapFile,
902
- image: beatmapPage.beatmaps?.image,
903
- starRating: beatmapPage.beatmaps?.starRating,
904
- owner: beatmapPage.owner,
905
- ownerUsername: beatmapPage.profiles?.username,
906
- ownerAvatar: beatmapPage.profiles?.avatar_url,
907
- id: beatmapPage.id,
908
- status: beatmapPage.status,
909
- nominations: beatmapPage.nominations as number[],
910
- },
911
- });
912
- }
245
+ */
913
246
  import { Schema as GetBeatmapPageById } from "./api/getBeatmapPageById"
914
247
  export { Schema as SchemaGetBeatmapPageById } from "./api/getBeatmapPageById"
915
248
  export const getBeatmapPageById = handleApi({url:"/api/getBeatmapPageById",...GetBeatmapPageById})
@@ -959,118 +292,7 @@ export const Schema = {
959
292
  )
960
293
  .optional(),
961
294
  }),
962
- };
963
-
964
- export async function POST(request: Request): Promise<NextResponse> {
965
- return protectedApi({
966
- request,
967
- schema: Schema,
968
- authorization: () => {},
969
- activity: handler,
970
- });
971
- }
972
-
973
- export async function handler(
974
- data: (typeof Schema)["input"]["_type"]
975
- ): Promise<NextResponse<(typeof Schema)["output"]["_type"]>> {
976
- const result = await getBeatmaps(data);
977
- return NextResponse.json(result);
978
- }
979
-
980
- const VIEW_PER_PAGE = 50;
981
-
982
- export async function getBeatmaps(data: (typeof Schema)["input"]["_type"]) {
983
- const startPage = (data.page - 1) * VIEW_PER_PAGE;
984
- const endPage = startPage + VIEW_PER_PAGE - 1;
985
- const countQuery = await supabase
986
- .from("beatmapPages")
987
- .select("id", { count: "exact", head: true });
988
-
989
- let qry = supabase
990
- .from("beatmapPages")
991
- .select(
992
- `
993
- owner,
994
- created_at,
995
- id,
996
- status,
997
- tags,
998
- beatmaps!inner(
999
- playcount,
1000
- ranked,
1001
- beatmapFile,
1002
- image,
1003
- starRating,
1004
- difficulty,
1005
- length,
1006
- title
1007
- ),
1008
- profiles!inner(
1009
- username
1010
- )`
1011
- )
1012
- .order("created_at", { ascending: false });
1013
-
1014
- if (data.textFilter) {
1015
- qry = qry.ilike("beatmaps.title", `%${data.textFilter}%`);
1016
- }
1017
-
1018
- if (data.authorFilter) {
1019
- qry = qry.ilike("profiles.username", `%${data.authorFilter}%`);
1020
- }
1021
-
1022
- if (data.tagsFilter) {
1023
- qry = qry.ilike("tags", `%${data.tagsFilter}%`);
1024
- }
1025
-
1026
- if (data.minStars) {
1027
- qry = qry.gt("beatmaps.starRating", data.minStars);
1028
- }
1029
-
1030
- if (data.maxStars) {
1031
- qry = qry.lt("beatmaps.starRating", data.maxStars);
1032
- }
1033
-
1034
- if (data.minLength) {
1035
- qry = qry.gt("beatmaps.length", data.minLength);
1036
- }
1037
-
1038
- if (data.maxLength) {
1039
- qry = qry.lt("beatmaps.length", data.maxLength);
1040
- }
1041
-
1042
- if (data.status) {
1043
- qry = qry.eq("status", data.status);
1044
- }
1045
-
1046
- if (data.creator !== undefined) {
1047
- qry = qry.eq("owner", data.creator);
1048
- }
1049
-
1050
- let queryData = await qry.range(startPage, endPage);
1051
-
1052
- return {
1053
- total: countQuery.count || 0,
1054
- viewPerPage: VIEW_PER_PAGE,
1055
- currentPage: data.page,
1056
- beatmaps: queryData.data?.map((beatmapPage) => ({
1057
- id: beatmapPage.id,
1058
- tags: beatmapPage.tags,
1059
- playcount: beatmapPage.beatmaps?.playcount,
1060
- created_at: beatmapPage.created_at,
1061
- difficulty: beatmapPage.beatmaps?.difficulty,
1062
- title: beatmapPage.beatmaps?.title,
1063
- ranked: beatmapPage.beatmaps?.ranked,
1064
- length: beatmapPage.beatmaps?.length,
1065
- beatmapFile: beatmapPage.beatmaps?.beatmapFile,
1066
- image: beatmapPage.beatmaps?.image,
1067
- starRating: beatmapPage.beatmaps?.starRating,
1068
- owner: beatmapPage.owner,
1069
- status: beatmapPage.status,
1070
- ownerUsername: beatmapPage.profiles?.username,
1071
- })),
1072
- };
1073
- }
295
+ */
1074
296
  import { Schema as GetBeatmaps } from "./api/getBeatmaps"
1075
297
  export { Schema as SchemaGetBeatmaps } from "./api/getBeatmaps"
1076
298
  export const getBeatmaps = handleApi({url:"/api/getBeatmaps",...GetBeatmaps})
@@ -1102,77 +324,7 @@ export const Schema = {
1102
324
  )
1103
325
  .optional(),
1104
326
  }),
1105
- };
1106
-
1107
- export async function POST(request: Request): Promise<NextResponse> {
1108
- return protectedApi({
1109
- request,
1110
- schema: Schema,
1111
- authorization: () => {},
1112
- activity: handler,
1113
- });
1114
- }
1115
-
1116
- export async function handler(
1117
- data: (typeof Schema)["input"]["_type"]
1118
- ): Promise<NextResponse<(typeof Schema)["output"]["_type"]>> {
1119
- const result = await getLeaderboard(data.page, data.session);
1120
- return NextResponse.json(result);
1121
- }
1122
-
1123
- const VIEW_PER_PAGE = 50;
1124
-
1125
- export async function getLeaderboard(page = 1, session: string) {
1126
- const getUserData = await getUser({ session });
1127
-
1128
- let leaderPosition = 0;
1129
-
1130
- if (getUserData) {
1131
- let { data: queryData, error } = await supabase
1132
- .from("profiles")
1133
- .select("*")
1134
- .eq("uid", getUserData.data.user.id)
1135
- .single();
1136
-
1137
- if (queryData) {
1138
- const { count: playersWithMorePoints, error: rankError } = await supabase
1139
- .from("profiles")
1140
- .select("*", { count: "exact", head: true })
1141
- .gt("skill_points", queryData.skill_points);
1142
-
1143
- leaderPosition = (playersWithMorePoints || 0) + 1;
1144
- }
1145
- }
1146
-
1147
- const startPage = (page - 1) * VIEW_PER_PAGE;
1148
- const endPage = startPage + VIEW_PER_PAGE - 1;
1149
- const countQuery = await supabase
1150
- .from("profiles")
1151
- .select("ban", { count: "exact", head: true })
1152
- .neq("ban", "excluded");
1153
-
1154
- let { data: queryData, error } = await supabase
1155
- .from("profiles")
1156
- .select("*")
1157
- .neq("ban", "excluded")
1158
- .order("skill_points", { ascending: false })
1159
- .range(startPage, endPage);
1160
-
1161
- return {
1162
- total: countQuery.count || 0,
1163
- viewPerPage: VIEW_PER_PAGE,
1164
- currentPage: page,
1165
- userPosition: leaderPosition,
1166
- leaderboard: queryData?.map((user) => ({
1167
- flag: user.flag,
1168
- id: user.id,
1169
- play_count: user.play_count,
1170
- skill_points: user.skill_points,
1171
- total_score: user.total_score,
1172
- username: user.username,
1173
- })),
1174
- };
1175
- }
327
+ */
1176
328
  import { Schema as GetLeaderboard } from "./api/getLeaderboard"
1177
329
  export { Schema as SchemaGetLeaderboard } from "./api/getLeaderboard"
1178
330
  export const getLeaderboard = handleApi({url:"/api/getLeaderboard",...GetLeaderboard})
@@ -1193,62 +345,7 @@ export const Schema = {
1193
345
  url: z.string().optional(),
1194
346
  objectKey: z.string().optional(),
1195
347
  }),
1196
- };
1197
-
1198
- export async function POST(request: Request): Promise<NextResponse> {
1199
- return protectedApi({
1200
- request,
1201
- schema: Schema,
1202
- authorization: validUser,
1203
- activity: handler,
1204
- });
1205
- }
1206
-
1207
- export async function handler({
1208
- mapName,
1209
- session,
1210
- contentLength,
1211
- contentType,
1212
- intrinsicToken,
1213
- }: (typeof Schema)["input"]["_type"]): Promise<
1214
- NextResponse<(typeof Schema)["output"]["_type"]>
1215
- > {
1216
- const user = (await supabase.auth.getUser(session)).data.user!;
1217
-
1218
- if (!validateIntrinsicToken(intrinsicToken)) {
1219
- return NextResponse.json({
1220
- error: "Invalid intrinsic token",
1221
- });
1222
- }
1223
-
1224
- if (contentLength > 50000000) {
1225
- return NextResponse.json({
1226
- error: "Max content length exceeded.",
1227
- });
1228
- }
1229
-
1230
- if (contentType !== "application/octet-stream") {
1231
- return NextResponse.json({
1232
- error: "Unnacceptable format",
1233
- });
1234
- }
1235
-
1236
- const key = `rhythia-${mapName ? mapName : user.id}-${Date.now()}.sspm`;
1237
- const command = new PutObjectCommand({
1238
- Bucket: "rhthia-avatars",
1239
- Key: key,
1240
- ContentLength: contentLength,
1241
- ContentType: contentType,
1242
- });
1243
-
1244
- const presigned = await getSignedUrl(s3Client, command, {
1245
- expiresIn: 3600,
1246
- });
1247
- return NextResponse.json({
1248
- url: presigned,
1249
- objectKey: key,
1250
- });
1251
- }
348
+ */
1252
349
  import { Schema as GetMapUploadUrl } from "./api/getMapUploadUrl"
1253
350
  export { Schema as SchemaGetMapUploadUrl } from "./api/getMapUploadUrl"
1254
351
  export const getMapUploadUrl = handleApi({url:"/api/getMapUploadUrl",...GetMapUploadUrl})
@@ -1284,97 +381,7 @@ export const Schema = {
1284
381
  })
1285
382
  .optional(),
1286
383
  }),
1287
- };
1288
-
1289
- export async function POST(request: Request): Promise<NextResponse> {
1290
- return protectedApi({
1291
- request,
1292
- schema: Schema,
1293
- authorization: () => {},
1294
- activity: handler,
1295
- });
1296
- }
1297
-
1298
- export async function handler(
1299
- data: (typeof Schema)["input"]["_type"],
1300
- req: Request
1301
- ): Promise<NextResponse<(typeof Schema)["output"]["_type"]>> {
1302
- let profiles: Database["public"]["Tables"]["profiles"]["Row"][] = [];
1303
-
1304
- // Fetch by id
1305
- if (data.id !== undefined && data.id !== null) {
1306
- let { data: queryData, error } = await supabase
1307
- .from("profiles")
1308
- .select("*")
1309
- .eq("id", data.id);
1310
-
1311
- console.log(profiles, error);
1312
-
1313
- if (!queryData?.length) {
1314
- return NextResponse.json(
1315
- {
1316
- error: "User not found",
1317
- },
1318
- { status: 404 }
1319
- );
1320
- }
1321
-
1322
- profiles = queryData;
1323
- } else {
1324
- // Fetch by session id
1325
- const user = (await supabase.auth.getUser(data.session)).data.user;
1326
-
1327
- if (user) {
1328
- let { data: queryData, error } = await supabase
1329
- .from("profiles")
1330
- .select("*")
1331
- .eq("uid", user.id);
1332
-
1333
- if (!queryData?.length) {
1334
- const geo = geolocation(req);
1335
- const data = await supabase
1336
- .from("profiles")
1337
- .upsert({
1338
- uid: user.id,
1339
- about_me: "",
1340
- avatar_url:
1341
- "https://rhthia-avatars.s3.eu-central-003.backblazeb2.com/user-avatar-1725309193296-72002e6b-321c-4f60-a692-568e0e75147d",
1342
- badges: [],
1343
- username: `${user.user_metadata.full_name.slice(0, 20)}${Math.round(
1344
- Math.random() * 900000 + 100000
1345
- )}`,
1346
- computedUsername: `${user.user_metadata.full_name.slice(
1347
- 0,
1348
- 20
1349
- )}${Math.round(Math.random() * 900000 + 100000)}`.toLowerCase(),
1350
- flag: (geo.country || "US").toUpperCase(),
1351
- created_at: Date.now(),
1352
- })
1353
- .select();
1354
-
1355
- profiles = data.data!;
1356
- } else {
1357
- profiles = queryData;
1358
- }
1359
- }
1360
- }
1361
-
1362
- const user = profiles[0];
1363
-
1364
- // Query to count how many players have more skill points than the specific player
1365
- const { count: playersWithMorePoints, error: rankError } = await supabase
1366
- .from("profiles")
1367
- .select("*", { count: "exact", head: true })
1368
- .neq("ban", "excluded")
1369
- .gt("skill_points", user.skill_points);
1370
-
1371
- return NextResponse.json({
1372
- user: {
1373
- ...user,
1374
- position: (playersWithMorePoints || 0) + 1,
1375
- },
1376
- });
1377
- }
384
+ */
1378
385
  import { Schema as GetProfile } from "./api/getProfile"
1379
386
  export { Schema as SchemaGetProfile } from "./api/getProfile"
1380
387
  export const getProfile = handleApi({url:"/api/getProfile",...GetProfile})
@@ -1389,36 +396,7 @@ export const Schema = {
1389
396
  beatmaps: z.number(),
1390
397
  scores: z.number(),
1391
398
  }),
1392
- };
1393
-
1394
- export async function POST(request: Request) {
1395
- return protectedApi({
1396
- request,
1397
- schema: Schema,
1398
- authorization: () => {},
1399
- activity: handler,
1400
- });
1401
- }
1402
-
1403
- export async function handler(data: (typeof Schema)["input"]["_type"]) {
1404
- const countProfilesQuery = await supabase
1405
- .from("profiles")
1406
- .select("*", { count: "exact", head: true });
1407
-
1408
- const countBeatmapsQuery = await supabase
1409
- .from("beatmaps")
1410
- .select("*", { count: "exact", head: true });
1411
-
1412
- const countScoresQuery = await supabase
1413
- .from("scores")
1414
- .select("*", { count: "exact", head: true });
1415
-
1416
- return NextResponse.json({
1417
- beatmaps: countBeatmapsQuery.count,
1418
- profiles: countProfilesQuery.count,
1419
- scores: countScoresQuery.count,
1420
- });
1421
- }
399
+ */
1422
400
  import { Schema as GetPublicStats } from "./api/getPublicStats"
1423
401
  export { Schema as SchemaGetPublicStats } from "./api/getPublicStats"
1424
402
  export const getPublicStats = handleApi({url:"/api/getPublicStats",...GetPublicStats})
@@ -1451,59 +429,7 @@ export const Schema = {
1451
429
  })
1452
430
  .optional(),
1453
431
  }),
1454
- };
1455
-
1456
- export async function POST(request: Request): Promise<NextResponse> {
1457
- return protectedApi({
1458
- request,
1459
- schema: Schema,
1460
- authorization: () => {},
1461
- activity: handler,
1462
- });
1463
- }
1464
-
1465
- export async function handler(
1466
- data: (typeof Schema)["input"]["_type"],
1467
- req: Request
1468
- ): Promise<NextResponse<(typeof Schema)["output"]["_type"]>> {
1469
- let { data: score, error: errorlast } = await supabase
1470
- .from("scores")
1471
- .select(
1472
- `
1473
- *,
1474
- beatmaps (
1475
- difficulty,
1476
- noteCount,
1477
- title
1478
- ),
1479
- profiles (
1480
- username
1481
- )
1482
- `
1483
- )
1484
- .eq("id", data.id)
1485
- .single();
1486
-
1487
- if (!score) return NextResponse.json({});
1488
-
1489
- return NextResponse.json({
1490
- score: {
1491
- created_at: score.created_at,
1492
- id: score.id,
1493
- passed: score.passed,
1494
- userId: score.userId,
1495
- awarded_sp: score.awarded_sp,
1496
- beatmapHash: score.beatmapHash,
1497
- misses: score.misses,
1498
- songId: score.songId,
1499
- beatmapDifficulty: score.beatmaps?.difficulty,
1500
- beatmapNotes: score.beatmaps?.noteCount,
1501
- beatmapTitle: score.beatmaps?.title,
1502
- username: score.profiles?.username,
1503
- speed: score.speed,
1504
- },
1505
- });
1506
- }
432
+ */
1507
433
  import { Schema as GetScore } from "./api/getScore"
1508
434
  export { Schema as SchemaGetScore } from "./api/getScore"
1509
435
  export const getScore = handleApi({url:"/api/getScore",...GetScore})
@@ -1556,107 +482,7 @@ export const Schema = {
1556
482
  )
1557
483
  .optional(),
1558
484
  }),
1559
- };
1560
-
1561
- export async function POST(request: Request): Promise<NextResponse> {
1562
- return protectedApi({
1563
- request,
1564
- schema: Schema,
1565
- authorization: () => {},
1566
- activity: handler,
1567
- });
1568
- }
1569
-
1570
- export async function handler(
1571
- data: (typeof Schema)["input"]["_type"],
1572
- req: Request
1573
- ): Promise<NextResponse<(typeof Schema)["output"]["_type"]>> {
1574
- let { data: scores1, error: errorlast } = await supabase
1575
- .from("scores")
1576
- .select(
1577
- `
1578
- *,
1579
- beatmaps (
1580
- difficulty,
1581
- noteCount,
1582
- title
1583
- )
1584
- `
1585
- )
1586
- .eq("userId", data.id)
1587
- .eq("passed", true)
1588
- .order("created_at", { ascending: false })
1589
- .limit(10);
1590
-
1591
- let { data: scores2, error: errorsp } = await supabase
1592
- .from("scores")
1593
- .select(
1594
- `
1595
- *,
1596
- beatmaps (
1597
- difficulty,
1598
- noteCount,
1599
- title
1600
- )
1601
- `
1602
- )
1603
- .eq("userId", data.id)
1604
- .neq("awarded_sp", 0)
1605
- .eq("passed", true)
1606
- .order("awarded_sp", { ascending: false });
1607
-
1608
- if (scores2 == null) return NextResponse.json({ error: "No scores" });
1609
-
1610
- let hashMap: Record<string, { awarded_sp: number; score: any }> = {};
1611
-
1612
- for (const score of scores2) {
1613
- const { beatmapHash, awarded_sp } = score;
1614
-
1615
- if (!beatmapHash || !awarded_sp) continue;
1616
-
1617
- if (!hashMap[beatmapHash] || hashMap[beatmapHash].awarded_sp < awarded_sp) {
1618
- hashMap[beatmapHash] = { awarded_sp, score };
1619
- }
1620
- }
1621
-
1622
- const values = Object.values(hashMap);
1623
- let vals = values
1624
- .sort((a, b) => b.awarded_sp - a.awarded_sp)
1625
- .slice(0, 10)
1626
- .map((e) => e.score);
1627
-
1628
- return NextResponse.json({
1629
- lastDay: scores1?.map((s) => ({
1630
- created_at: s.created_at,
1631
- id: s.id,
1632
- passed: s.passed,
1633
- userId: s.userId,
1634
- awarded_sp: s.awarded_sp,
1635
- beatmapHash: s.beatmapHash,
1636
- misses: s.misses,
1637
- songId: s.songId,
1638
- beatmapDifficulty: s.beatmaps?.difficulty,
1639
- beatmapNotes: s.beatmaps?.noteCount,
1640
- beatmapTitle: s.beatmaps?.title,
1641
- speed: s.speed,
1642
- })),
1643
- top: vals?.map((s) => ({
1644
- created_at: s.created_at,
1645
- id: s.id,
1646
- passed: s.passed,
1647
- userId: s.userId,
1648
- awarded_sp: s.awarded_sp,
1649
- beatmapHash: s.beatmapHash,
1650
- misses: s.misses,
1651
- rank: s.rank,
1652
- songId: s.songId,
1653
- beatmapDifficulty: s.beatmaps?.difficulty,
1654
- beatmapNotes: s.beatmaps?.noteCount,
1655
- beatmapTitle: s.beatmaps?.title,
1656
- speed: s.speed,
1657
- })),
1658
- });
1659
- }
485
+ */
1660
486
  import { Schema as GetUserScores } from "./api/getUserScores"
1661
487
  export { Schema as SchemaGetUserScores } from "./api/getUserScores"
1662
488
  export const getUserScores = handleApi({url:"/api/getUserScores",...GetUserScores})
@@ -1672,60 +498,7 @@ export const Schema = {
1672
498
  output: z.object({
1673
499
  error: z.string().optional(),
1674
500
  }),
1675
- };
1676
-
1677
- export async function POST(request: Request) {
1678
- return protectedApi({
1679
- request,
1680
- schema: Schema,
1681
- authorization: validUser,
1682
- activity: handler,
1683
- });
1684
- }
1685
-
1686
- export async function handler(data: (typeof Schema)["input"]["_type"]) {
1687
- const user = (await supabase.auth.getUser(data.session)).data.user!;
1688
- let { data: queryUserData, error: userError } = await supabase
1689
- .from("profiles")
1690
- .select("*")
1691
- .eq("uid", user.id)
1692
- .single();
1693
-
1694
- if (!queryUserData) {
1695
- return NextResponse.json({ error: "Can't find user" });
1696
- }
1697
-
1698
- const tags = (queryUserData?.badges || []) as string[];
1699
-
1700
- if (!tags.includes("RCT")) {
1701
- return NextResponse.json({ error: "Only RCTs can nominate maps!" });
1702
- }
1703
-
1704
- const { data: mapData, error } = await supabase
1705
- .from("beatmapPages")
1706
- .select("id,nominations,owner")
1707
- .eq("id", data.mapId)
1708
- .single();
1709
-
1710
- if (!mapData) {
1711
- return NextResponse.json({ error: "Bad map" });
1712
- }
1713
-
1714
- if (mapData.owner == queryUserData.id) {
1715
- return NextResponse.json({ error: "Can't nominate own map" });
1716
- }
1717
-
1718
- if ((mapData.nominations as number[]).includes(queryUserData.id)) {
1719
- return NextResponse.json({ error: "Already nominated" });
1720
- }
1721
-
1722
- await supabase.from("beatmapPages").upsert({
1723
- id: data.mapId,
1724
- nominations: [...(mapData.nominations! as number[]), queryUserData.id],
1725
- });
1726
-
1727
- return NextResponse.json({});
1728
- }
501
+ */
1729
502
  import { Schema as NominateMap } from "./api/nominateMap"
1730
503
  export { Schema as SchemaNominateMap } from "./api/nominateMap"
1731
504
  export const nominateMap = handleApi({url:"/api/nominateMap",...NominateMap})
@@ -1742,48 +515,7 @@ export const Schema = {
1742
515
  output: z.strictObject({
1743
516
  error: z.string().optional(),
1744
517
  }),
1745
- };
1746
-
1747
- export async function POST(request: Request): Promise<NextResponse> {
1748
- return protectedApi({
1749
- request,
1750
- schema: Schema,
1751
- authorization: validUser,
1752
- activity: handler,
1753
- });
1754
- }
1755
-
1756
- export async function handler({
1757
- session,
1758
- page,
1759
- content,
1760
- }: (typeof Schema)["input"]["_type"]): Promise<
1761
- NextResponse<(typeof Schema)["output"]["_type"]>
1762
- > {
1763
- const user = (await supabase.auth.getUser(session)).data.user!;
1764
- let { data: userData, error: userError } = await supabase
1765
- .from("profiles")
1766
- .select("*")
1767
- .eq("uid", user.id)
1768
- .single();
1769
-
1770
- if (!userData) return NextResponse.json({ error: "No user." });
1771
-
1772
- const upserted = await supabase
1773
- .from("beatmapPageComments")
1774
- .upsert({
1775
- beatmapPage: page,
1776
- owner: userData.id,
1777
- content,
1778
- })
1779
- .select("*")
1780
- .single();
1781
-
1782
- if (upserted.error?.message.length) {
1783
- return NextResponse.json({ error: upserted.error.message });
1784
- }
1785
- return NextResponse.json({});
1786
- }
518
+ */
1787
519
  import { Schema as PostBeatmapComment } from "./api/postBeatmapComment"
1788
520
  export { Schema as SchemaPostBeatmapComment } from "./api/postBeatmapComment"
1789
521
  export const postBeatmapComment = handleApi({url:"/api/postBeatmapComment",...PostBeatmapComment})
@@ -1799,55 +531,7 @@ export const Schema = {
1799
531
  output: z.object({
1800
532
  error: z.string().optional(),
1801
533
  }),
1802
- };
1803
-
1804
- export async function POST(request: Request) {
1805
- return protectedApi({
1806
- request,
1807
- schema: Schema,
1808
- authorization: validUser,
1809
- activity: handler,
1810
- });
1811
- }
1812
-
1813
- export async function handler(data: (typeof Schema)["input"]["_type"]) {
1814
- const user = (await supabase.auth.getUser(data.session)).data.user!;
1815
- let { data: queryUserData, error: userError } = await supabase
1816
- .from("profiles")
1817
- .select("*")
1818
- .eq("uid", user.id)
1819
- .single();
1820
-
1821
- if (!queryUserData) {
1822
- return NextResponse.json({ error: "Can't find user" });
1823
- }
1824
-
1825
- const tags = (queryUserData?.badges || []) as string[];
1826
-
1827
- if (!tags.includes("Bot")) {
1828
- return NextResponse.json({ error: "Only Bots can force-rank maps!" });
1829
- }
1830
-
1831
- const { data: mapData, error } = await supabase
1832
- .from("beatmapPages")
1833
- .select("id,nominations,owner,status")
1834
- .eq("owner", user.id)
1835
- .eq("status", "UNRANKED");
1836
-
1837
- if (!mapData) {
1838
- return NextResponse.json({ error: "Bad map" });
1839
- }
1840
-
1841
- for (const element of mapData) {
1842
- await supabase.from("beatmapPages").upsert({
1843
- id: element.id,
1844
- nominations: [queryUserData.id, queryUserData.id],
1845
- status: "RANKED",
1846
- });
1847
- }
1848
-
1849
- return NextResponse.json({});
1850
- }
534
+ */
1851
535
  import { Schema as RankMapsArchive } from "./api/rankMapsArchive"
1852
536
  export { Schema as SchemaRankMapsArchive } from "./api/rankMapsArchive"
1853
537
  export const rankMapsArchive = handleApi({url:"/api/rankMapsArchive",...RankMapsArchive})
@@ -1870,28 +554,7 @@ export const Schema = {
1870
554
  )
1871
555
  .optional(),
1872
556
  }),
1873
- };
1874
-
1875
- export async function POST(request: Request) {
1876
- return protectedApi({
1877
- request,
1878
- schema: Schema,
1879
- authorization: () => {},
1880
- activity: handler,
1881
- });
1882
- }
1883
-
1884
- export async function handler(data: (typeof Schema)["input"]["_type"]) {
1885
- const { data: searchData, error } = await supabase
1886
- .from("profiles")
1887
- .select("id,username")
1888
- .neq("ban", "excluded")
1889
- .ilike("username", `%${data.text}%`)
1890
- .limit(10);
1891
- return NextResponse.json({
1892
- results: searchData || [],
1893
- });
1894
- }
557
+ */
1895
558
  import { Schema as SearchUsers } from "./api/searchUsers"
1896
559
  export { Schema as SchemaSearchUsers } from "./api/searchUsers"
1897
560
  export const searchUsers = handleApi({url:"/api/searchUsers",...SearchUsers})
@@ -1916,188 +579,7 @@ export const Schema = {
1916
579
  output: z.object({
1917
580
  error: z.string().optional(),
1918
581
  }),
1919
- };
1920
-
1921
- function easeInExpoDeq(x: number) {
1922
- return x === 0 ? 0 : Math.pow(2, 50 * x - 50);
1923
- }
1924
-
1925
- export function calculatePerformancePoints(
1926
- starRating: number,
1927
- accuracy: number
1928
- ) {
1929
- return Math.round(
1930
- Math.pow((starRating * easeInExpoDeq(accuracy) * 100) / 2, 2) / 1000
1931
- );
1932
- }
1933
-
1934
- export async function POST(request: Request): Promise<NextResponse> {
1935
- return protectedApi({
1936
- request,
1937
- schema: Schema,
1938
- authorization: validUser,
1939
- activity: handler,
1940
- });
1941
- }
1942
-
1943
- export async function handler({
1944
- data,
1945
- session,
1946
- }: (typeof Schema)["input"]["_type"]): Promise<
1947
- NextResponse<(typeof Schema)["output"]["_type"]>
1948
- > {
1949
- return NextResponse.json(
1950
- {
1951
- error: "Disabled",
1952
- },
1953
- { status: 500 }
1954
- );
1955
- const user = (await supabase.auth.getUser(session)).data.user!;
1956
-
1957
- let { data: userData, error: userError } = await supabase
1958
- .from("profiles")
1959
- .select("*")
1960
- .eq("uid", user.id)
1961
- .single();
1962
-
1963
- if (!userData)
1964
- return NextResponse.json(
1965
- {
1966
- error: "User doesn't exist",
1967
- },
1968
- { status: 500 }
1969
- );
1970
-
1971
- console.log(userData);
1972
- let { data: beatmaps, error } = await supabase
1973
- .from("beatmaps")
1974
- .select("*")
1975
- .eq("beatmapHash", data.mapHash)
1976
- .single();
1977
-
1978
- let { data: beatmapPages, error: bpError } = await supabase
1979
- .from("beatmapPages")
1980
- .select("*")
1981
- .eq("latestBeatmapHash", data.mapHash)
1982
- .single();
1983
-
1984
- if (!beatmapPages) {
1985
- return NextResponse.json(
1986
- {
1987
- error: "Map not submitted",
1988
- },
1989
- { status: 500 }
1990
- );
1991
- }
1992
-
1993
- if (!beatmaps) {
1994
- return NextResponse.json(
1995
- {
1996
- error: "Map not submitted",
1997
- },
1998
- { status: 500 }
1999
- );
2000
- }
2001
-
2002
- if (beatmaps.noteCount !== data.mapNoteCount) {
2003
- return NextResponse.json(
2004
- {
2005
- error: "Wrong map",
2006
- },
2007
- { status: 500 }
2008
- );
2009
- }
2010
-
2011
- await supabase.from("beatmaps").upsert({
2012
- beatmapHash: data.mapHash,
2013
- playcount: (beatmaps.playcount || 1) + 1,
2014
- });
2015
-
2016
- let passed = true;
2017
-
2018
- // Pass invalidation
2019
- if (data.misses + data.hits !== beatmaps.noteCount) {
2020
- passed = false;
2021
- }
2022
-
2023
- const accurracy = data.hits / beatmaps.noteCount;
2024
- let awarded_sp = 0;
2025
-
2026
- console.log(
2027
- data.misses + data.hits == beatmaps.noteCount,
2028
- data.misses + data.hits,
2029
- beatmaps.noteCount
2030
- );
2031
-
2032
- if (beatmaps.starRating) {
2033
- awarded_sp = calculatePerformancePoints(
2034
- data.speed * beatmaps.starRating,
2035
- accurracy
2036
- );
2037
- }
2038
-
2039
- if (beatmapPages.status == "UNRANKED") {
2040
- awarded_sp = 0;
2041
- }
2042
-
2043
- console.log("p1");
2044
- await supabase.from("scores").upsert({
2045
- beatmapHash: data.mapHash,
2046
- replayHwid: data.relayHwid,
2047
- songId: data.songId,
2048
- userId: userData.id,
2049
- passed,
2050
- misses: data.misses,
2051
- awarded_sp: Math.round(awarded_sp * 100) / 100,
2052
- speed: data.speed,
2053
- });
2054
- console.log("p2");
2055
-
2056
- let totalSp = 0;
2057
- let { data: scores2, error: errorsp } = await supabase
2058
- .from("scores")
2059
- .select(`awarded_sp,beatmapHash`)
2060
- .eq("userId", userData.id)
2061
- .neq("awarded_sp", 0)
2062
- .eq("passed", true)
2063
- .order("awarded_sp", { ascending: false });
2064
-
2065
- if (scores2 == null) return NextResponse.json({ error: "No scores" });
2066
-
2067
- let hashMap: Record<string, number> = {};
2068
-
2069
- for (const score of scores2) {
2070
- const { beatmapHash, awarded_sp } = score;
2071
-
2072
- if (!beatmapHash || !awarded_sp) continue;
2073
-
2074
- if (!hashMap[beatmapHash] || hashMap[beatmapHash] < awarded_sp) {
2075
- hashMap[beatmapHash] = awarded_sp;
2076
- }
2077
- }
2078
- let weight = 100;
2079
- const values = Object.values(hashMap);
2080
- values.sort((a, b) => b - a);
2081
-
2082
- for (const score of values) {
2083
- totalSp += ((score || 0) * weight) / 100;
2084
- weight -= 1;
2085
-
2086
- if (weight == 0) {
2087
- break;
2088
- }
2089
- }
2090
-
2091
- await supabase.from("profiles").upsert({
2092
- id: userData.id,
2093
- play_count: (userData.play_count || 0) + 1,
2094
- skill_points: Math.round(totalSp * 100) / 100,
2095
- squares_hit: (userData.squares_hit || 0) + data.hits,
2096
- });
2097
- console.log("p3");
2098
-
2099
- return NextResponse.json({});
2100
- }
582
+ */
2101
583
  import { Schema as SubmitScore } from "./api/submitScore"
2102
584
  export { Schema as SchemaSubmitScore } from "./api/submitScore"
2103
585
  export const submitScore = handleApi({url:"/api/submitScore",...SubmitScore})
@@ -2116,75 +598,7 @@ export const Schema = {
2116
598
  output: z.strictObject({
2117
599
  error: z.string().optional(),
2118
600
  }),
2119
- };
2120
-
2121
- export async function POST(request: Request): Promise<NextResponse> {
2122
- return protectedApi({
2123
- request,
2124
- schema: Schema,
2125
- authorization: validUser,
2126
- activity: handler,
2127
- });
2128
- }
2129
-
2130
- export async function handler({
2131
- session,
2132
- beatmapHash,
2133
- id,
2134
- description,
2135
- tags,
2136
- }: (typeof Schema)["input"]["_type"]): Promise<
2137
- NextResponse<(typeof Schema)["output"]["_type"]>
2138
- > {
2139
- const user = (await supabase.auth.getUser(session)).data.user!;
2140
- let { data: userData, error: userError } = await supabase
2141
- .from("profiles")
2142
- .select("*")
2143
- .eq("uid", user.id)
2144
- .single();
2145
-
2146
- let { data: pageData, error: pageError } = await supabase
2147
- .from("beatmapPages")
2148
- .select("*")
2149
- .eq("id", id)
2150
- .single();
2151
-
2152
- let { data: beatmapData, error: bmPageError } = await supabase
2153
- .from("beatmaps")
2154
- .select("*")
2155
- .eq("beatmapHash", beatmapHash)
2156
- .single();
2157
-
2158
- if (!userData) return NextResponse.json({ error: "No user." });
2159
- if (!beatmapData) return NextResponse.json({ error: "No beatmap." });
2160
-
2161
- if (userData.id !== pageData?.owner)
2162
- return NextResponse.json({ error: "Non-authz user." });
2163
-
2164
- if (pageData?.status !== "UNRANKED")
2165
- return NextResponse.json({ error: "Only unranked maps can be updated" });
2166
-
2167
- const upserted = await supabase
2168
- .from("beatmapPages")
2169
- .upsert({
2170
- id,
2171
- latestBeatmapHash: beatmapHash,
2172
- genre: "",
2173
- title: beatmapData.title,
2174
- status: "UNRANKED",
2175
- owner: userData.id,
2176
- description,
2177
- tags,
2178
- nominations: [],
2179
- })
2180
- .select("*")
2181
- .single();
2182
-
2183
- if (upserted.error?.message.length) {
2184
- return NextResponse.json({ error: upserted.error.message });
2185
- }
2186
- return NextResponse.json({});
2187
- }
601
+ */
2188
602
  import { Schema as UpdateBeatmapPage } from "./api/updateBeatmapPage"
2189
603
  export { Schema as SchemaUpdateBeatmapPage } from "./api/updateBeatmapPage"
2190
604
  export const updateBeatmapPage = handleApi({url:"/api/updateBeatmapPage",...UpdateBeatmapPage})