rhythia-api 105.0.0 → 107.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 +47 -0
- package/api/createBeatmapPage.ts +47 -0
- package/api/editProfile.ts +15 -0
- package/api/getLeaderboard.ts +3 -1
- package/api/getMapUploadUrl.ts +74 -0
- package/api/getProfile.ts +3 -1
- package/api/searchUsers.ts +1 -0
- package/api/updateBeatmapPage.ts +64 -0
- package/index.ts +20 -0
- package/package.json +3 -2
- package/scripts/test.ts +31 -0
- package/types/database.ts +49 -1
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
import { NextResponse } from "next/server";
|
|
2
|
+
import z from "zod";
|
|
3
|
+
import { protectedApi, validUser } from "../utils/requestUtils";
|
|
4
|
+
import { supabase } from "../utils/supabase";
|
|
5
|
+
import {
|
|
6
|
+
SSPMParsedMap,
|
|
7
|
+
SSPMParser,
|
|
8
|
+
} from "rhythia-star-calculator/src/sspmParser";
|
|
9
|
+
|
|
10
|
+
export const Schema = {
|
|
11
|
+
input: z.strictObject({
|
|
12
|
+
url: z.string(),
|
|
13
|
+
}),
|
|
14
|
+
output: z.strictObject({
|
|
15
|
+
hash: z.string().optional(),
|
|
16
|
+
error: z.string().optional(),
|
|
17
|
+
}),
|
|
18
|
+
};
|
|
19
|
+
|
|
20
|
+
export async function POST(request: Request): Promise<NextResponse> {
|
|
21
|
+
return protectedApi({
|
|
22
|
+
request,
|
|
23
|
+
schema: Schema,
|
|
24
|
+
authorization: validUser,
|
|
25
|
+
activity: handler,
|
|
26
|
+
});
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
export async function handler({
|
|
30
|
+
url,
|
|
31
|
+
}: (typeof Schema)["input"]["_type"]): Promise<
|
|
32
|
+
NextResponse<(typeof Schema)["output"]["_type"]>
|
|
33
|
+
> {
|
|
34
|
+
if (
|
|
35
|
+
!url.startsWith(`https://rhthia-avatars.s3.eu-central-003.backblazeb2.com/`)
|
|
36
|
+
)
|
|
37
|
+
return NextResponse.json({ error: "Invalid url" });
|
|
38
|
+
|
|
39
|
+
const request = await fetch(url);
|
|
40
|
+
const bytes = await request.arrayBuffer();
|
|
41
|
+
const parser = new SSPMParser(Buffer.from(bytes));
|
|
42
|
+
|
|
43
|
+
const parsedData = parser.parse();
|
|
44
|
+
|
|
45
|
+
console.log(parsedData);
|
|
46
|
+
return NextResponse.json({});
|
|
47
|
+
}
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
import { NextResponse } from "next/server";
|
|
2
|
+
import z from "zod";
|
|
3
|
+
import { protectedApi, validUser } from "../utils/requestUtils";
|
|
4
|
+
import { supabase } from "../utils/supabase";
|
|
5
|
+
|
|
6
|
+
export const Schema = {
|
|
7
|
+
input: z.strictObject({
|
|
8
|
+
session: z.string(),
|
|
9
|
+
}),
|
|
10
|
+
output: z.strictObject({
|
|
11
|
+
error: z.string().optional(),
|
|
12
|
+
id: z.number().optional(),
|
|
13
|
+
}),
|
|
14
|
+
};
|
|
15
|
+
|
|
16
|
+
export async function POST(request: Request): Promise<NextResponse> {
|
|
17
|
+
return protectedApi({
|
|
18
|
+
request,
|
|
19
|
+
schema: Schema,
|
|
20
|
+
authorization: validUser,
|
|
21
|
+
activity: handler,
|
|
22
|
+
});
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
export async function handler({
|
|
26
|
+
session,
|
|
27
|
+
}: (typeof Schema)["input"]["_type"]): Promise<
|
|
28
|
+
NextResponse<(typeof Schema)["output"]["_type"]>
|
|
29
|
+
> {
|
|
30
|
+
const user = (await supabase.auth.getUser(session)).data.user!;
|
|
31
|
+
let { data: userData, error: userError } = await supabase
|
|
32
|
+
.from("profiles")
|
|
33
|
+
.select("*")
|
|
34
|
+
.eq("uid", user.id)
|
|
35
|
+
.single();
|
|
36
|
+
|
|
37
|
+
if (!userData) return NextResponse.json({ error: "No user." });
|
|
38
|
+
|
|
39
|
+
const upserted = await supabase
|
|
40
|
+
.from("beatmapPages")
|
|
41
|
+
.upsert({
|
|
42
|
+
owner: userData.id,
|
|
43
|
+
})
|
|
44
|
+
.select("*")
|
|
45
|
+
.single();
|
|
46
|
+
return NextResponse.json({ id: upserted.data?.id });
|
|
47
|
+
}
|
package/api/editProfile.ts
CHANGED
|
@@ -47,6 +47,7 @@ export async function handler(
|
|
|
47
47
|
}
|
|
48
48
|
|
|
49
49
|
const user = (await supabase.auth.getUser(data.session)).data.user!;
|
|
50
|
+
|
|
50
51
|
let userData: Database["public"]["Tables"]["profiles"]["Update"];
|
|
51
52
|
|
|
52
53
|
// Find user's entry
|
|
@@ -67,6 +68,20 @@ export async function handler(
|
|
|
67
68
|
userData = queryUserData[0];
|
|
68
69
|
}
|
|
69
70
|
|
|
71
|
+
if (
|
|
72
|
+
userData.ban == "excluded" ||
|
|
73
|
+
userData.ban == "restricted" ||
|
|
74
|
+
userData.ban == "silenced"
|
|
75
|
+
) {
|
|
76
|
+
return NextResponse.json(
|
|
77
|
+
{
|
|
78
|
+
error:
|
|
79
|
+
"Silenced, restricted or excluded players can't update their profile.",
|
|
80
|
+
},
|
|
81
|
+
{ status: 404 }
|
|
82
|
+
);
|
|
83
|
+
}
|
|
84
|
+
|
|
70
85
|
const upsertPayload: Database["public"]["Tables"]["profiles"]["Update"] = {
|
|
71
86
|
id: userData.id,
|
|
72
87
|
computedUsername: data.data.username?.toLowerCase(),
|
package/api/getLeaderboard.ts
CHANGED
|
@@ -74,11 +74,13 @@ export async function getLeaderboard(page = 1, session: string) {
|
|
|
74
74
|
console.log(startPage, endPage);
|
|
75
75
|
const countQuery = await supabase
|
|
76
76
|
.from("profiles")
|
|
77
|
-
.select("*", { count: "exact", head: true })
|
|
77
|
+
.select("*", { count: "exact", head: true })
|
|
78
|
+
.neq("ban", "excluded");
|
|
78
79
|
|
|
79
80
|
let { data: queryData, error } = await supabase
|
|
80
81
|
.from("profiles")
|
|
81
82
|
.select("*")
|
|
83
|
+
.neq("ban", "excluded")
|
|
82
84
|
.order("skill_points", { ascending: false })
|
|
83
85
|
.range(startPage, endPage);
|
|
84
86
|
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
import { NextResponse } from "next/server";
|
|
2
|
+
import z from "zod";
|
|
3
|
+
import { protectedApi, validUser } from "../utils/requestUtils";
|
|
4
|
+
import { supabase } from "../utils/supabase";
|
|
5
|
+
|
|
6
|
+
import {
|
|
7
|
+
PutBucketCorsCommand,
|
|
8
|
+
PutObjectCommand,
|
|
9
|
+
S3Client,
|
|
10
|
+
} from "@aws-sdk/client-s3";
|
|
11
|
+
import { getSignedUrl } from "@aws-sdk/s3-request-presigner";
|
|
12
|
+
|
|
13
|
+
const s3Client = new S3Client({
|
|
14
|
+
region: "auto",
|
|
15
|
+
endpoint: "https://s3.eu-central-003.backblazeb2.com",
|
|
16
|
+
credentials: {
|
|
17
|
+
secretAccessKey: "K0039mm4iKsteQOXpZSzf0+VDzuH89U",
|
|
18
|
+
accessKeyId: "003c245e893e8060000000001",
|
|
19
|
+
},
|
|
20
|
+
});
|
|
21
|
+
|
|
22
|
+
export const Schema = {
|
|
23
|
+
input: z.strictObject({
|
|
24
|
+
session: z.string(),
|
|
25
|
+
contentLength: z.number(),
|
|
26
|
+
contentType: z.string(),
|
|
27
|
+
}),
|
|
28
|
+
output: z.strictObject({
|
|
29
|
+
error: z.string().optional(),
|
|
30
|
+
url: z.string().optional(),
|
|
31
|
+
objectKey: z.string().optional(),
|
|
32
|
+
}),
|
|
33
|
+
};
|
|
34
|
+
|
|
35
|
+
export async function POST(request: Request): Promise<NextResponse> {
|
|
36
|
+
return protectedApi({
|
|
37
|
+
request,
|
|
38
|
+
schema: Schema,
|
|
39
|
+
authorization: validUser,
|
|
40
|
+
activity: handler,
|
|
41
|
+
});
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
export async function handler({
|
|
45
|
+
session,
|
|
46
|
+
contentLength,
|
|
47
|
+
contentType,
|
|
48
|
+
}: (typeof Schema)["input"]["_type"]): Promise<
|
|
49
|
+
NextResponse<(typeof Schema)["output"]["_type"]>
|
|
50
|
+
> {
|
|
51
|
+
const user = (await supabase.auth.getUser(session)).data.user!;
|
|
52
|
+
|
|
53
|
+
if (contentLength > 50000000) {
|
|
54
|
+
return NextResponse.json({
|
|
55
|
+
error: "Max content length exceeded.",
|
|
56
|
+
});
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
const key = `beatmap-${Date.now()}-${user.id}`;
|
|
60
|
+
const command = new PutObjectCommand({
|
|
61
|
+
Bucket: "rhthia-avatars",
|
|
62
|
+
Key: key,
|
|
63
|
+
ContentLength: contentLength,
|
|
64
|
+
ContentType: contentType,
|
|
65
|
+
});
|
|
66
|
+
|
|
67
|
+
const presigned = await getSignedUrl(s3Client, command, {
|
|
68
|
+
expiresIn: 3600,
|
|
69
|
+
});
|
|
70
|
+
return NextResponse.json({
|
|
71
|
+
url: presigned,
|
|
72
|
+
objectKey: key,
|
|
73
|
+
});
|
|
74
|
+
}
|
package/api/getProfile.ts
CHANGED
|
@@ -21,6 +21,7 @@ export const Schema = {
|
|
|
21
21
|
flag: z.string().nullable(),
|
|
22
22
|
id: z.number(),
|
|
23
23
|
uid: z.string().nullable(),
|
|
24
|
+
ban: z.string().nullable(),
|
|
24
25
|
username: z.string().nullable(),
|
|
25
26
|
verified: z.boolean().nullable(),
|
|
26
27
|
play_count: z.number().nullable(),
|
|
@@ -86,7 +87,7 @@ export async function handler(
|
|
|
86
87
|
about_me: "",
|
|
87
88
|
avatar_url:
|
|
88
89
|
"https://rhthia-avatars.s3.eu-central-003.backblazeb2.com/user-avatar-1725309193296-72002e6b-321c-4f60-a692-568e0e75147d",
|
|
89
|
-
badges: [
|
|
90
|
+
badges: [],
|
|
90
91
|
username: `${user.user_metadata.full_name.slice(0, 20)}${Math.round(
|
|
91
92
|
Math.random() * 900000 + 100000
|
|
92
93
|
)}`,
|
|
@@ -112,6 +113,7 @@ export async function handler(
|
|
|
112
113
|
const { count: playersWithMorePoints, error: rankError } = await supabase
|
|
113
114
|
.from("profiles")
|
|
114
115
|
.select("*", { count: "exact", head: true })
|
|
116
|
+
.neq("ban", "excluded")
|
|
115
117
|
.gt("skill_points", user.skill_points);
|
|
116
118
|
|
|
117
119
|
return NextResponse.json({
|
package/api/searchUsers.ts
CHANGED
|
@@ -33,6 +33,7 @@ export async function handler(data: (typeof Schema)["input"]["_type"]) {
|
|
|
33
33
|
const { data: searchData, error } = await supabase
|
|
34
34
|
.from("profiles")
|
|
35
35
|
.select("id,username")
|
|
36
|
+
.neq("ban", "excluded")
|
|
36
37
|
.ilike("username", `%${data.text}%`)
|
|
37
38
|
.limit(10);
|
|
38
39
|
return NextResponse.json({
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
import { NextResponse } from "next/server";
|
|
2
|
+
import z from "zod";
|
|
3
|
+
import { protectedApi, validUser } from "../utils/requestUtils";
|
|
4
|
+
import { supabase } from "../utils/supabase";
|
|
5
|
+
|
|
6
|
+
export const Schema = {
|
|
7
|
+
input: z.strictObject({
|
|
8
|
+
session: z.string(),
|
|
9
|
+
id: z.number(),
|
|
10
|
+
beatmapHash: z.string(),
|
|
11
|
+
}),
|
|
12
|
+
output: z.strictObject({
|
|
13
|
+
error: z.string().optional(),
|
|
14
|
+
}),
|
|
15
|
+
};
|
|
16
|
+
|
|
17
|
+
export async function POST(request: Request): Promise<NextResponse> {
|
|
18
|
+
return protectedApi({
|
|
19
|
+
request,
|
|
20
|
+
schema: Schema,
|
|
21
|
+
authorization: validUser,
|
|
22
|
+
activity: handler,
|
|
23
|
+
});
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
export async function handler({
|
|
27
|
+
session,
|
|
28
|
+
beatmapHash,
|
|
29
|
+
id,
|
|
30
|
+
}: (typeof Schema)["input"]["_type"]): Promise<
|
|
31
|
+
NextResponse<(typeof Schema)["output"]["_type"]>
|
|
32
|
+
> {
|
|
33
|
+
const user = (await supabase.auth.getUser(session)).data.user!;
|
|
34
|
+
let { data: userData, error: userError } = await supabase
|
|
35
|
+
.from("profiles")
|
|
36
|
+
.select("*")
|
|
37
|
+
.eq("uid", user.id)
|
|
38
|
+
.single();
|
|
39
|
+
|
|
40
|
+
let { data: pageData, error: pageError } = await supabase
|
|
41
|
+
.from("beatmapPages")
|
|
42
|
+
.select("*")
|
|
43
|
+
.eq("id", id)
|
|
44
|
+
.single();
|
|
45
|
+
|
|
46
|
+
if (!userData) return NextResponse.json({ error: "No user." });
|
|
47
|
+
if (userData.id !== pageData?.owner)
|
|
48
|
+
return NextResponse.json({ error: "Non-authz user." });
|
|
49
|
+
|
|
50
|
+
const upserted = await supabase
|
|
51
|
+
.from("beatmapPages")
|
|
52
|
+
.upsert({
|
|
53
|
+
id,
|
|
54
|
+
latestBeatmapHash: beatmapHash,
|
|
55
|
+
owner: userData.id,
|
|
56
|
+
})
|
|
57
|
+
.select("*")
|
|
58
|
+
.single();
|
|
59
|
+
|
|
60
|
+
if (upserted.error) {
|
|
61
|
+
return NextResponse.json({ error: upserted.error.message });
|
|
62
|
+
}
|
|
63
|
+
return NextResponse.json({});
|
|
64
|
+
}
|
package/index.ts
CHANGED
|
@@ -1,5 +1,15 @@
|
|
|
1
1
|
import { handleApi } from "./handleApi"
|
|
2
2
|
|
|
3
|
+
// ./api/createBeatmap.ts API
|
|
4
|
+
import { Schema as CreateBeatmap } from "./api/createBeatmap"
|
|
5
|
+
export { Schema as SchemaCreateBeatmap } from "./api/createBeatmap"
|
|
6
|
+
export const createBeatmap = handleApi({url:"/api/createBeatmap",...CreateBeatmap})
|
|
7
|
+
|
|
8
|
+
// ./api/createBeatmapPage.ts API
|
|
9
|
+
import { Schema as CreateBeatmapPage } from "./api/createBeatmapPage"
|
|
10
|
+
export { Schema as SchemaCreateBeatmapPage } from "./api/createBeatmapPage"
|
|
11
|
+
export const createBeatmapPage = handleApi({url:"/api/createBeatmapPage",...CreateBeatmapPage})
|
|
12
|
+
|
|
3
13
|
// ./api/editAboutMe.ts API
|
|
4
14
|
import { Schema as EditAboutMe } from "./api/editAboutMe"
|
|
5
15
|
export { Schema as SchemaEditAboutMe } from "./api/editAboutMe"
|
|
@@ -20,6 +30,11 @@ import { Schema as GetLeaderboard } from "./api/getLeaderboard"
|
|
|
20
30
|
export { Schema as SchemaGetLeaderboard } from "./api/getLeaderboard"
|
|
21
31
|
export const getLeaderboard = handleApi({url:"/api/getLeaderboard",...GetLeaderboard})
|
|
22
32
|
|
|
33
|
+
// ./api/getMapUploadUrl.ts API
|
|
34
|
+
import { Schema as GetMapUploadUrl } from "./api/getMapUploadUrl"
|
|
35
|
+
export { Schema as SchemaGetMapUploadUrl } from "./api/getMapUploadUrl"
|
|
36
|
+
export const getMapUploadUrl = handleApi({url:"/api/getMapUploadUrl",...GetMapUploadUrl})
|
|
37
|
+
|
|
23
38
|
// ./api/getProfile.ts API
|
|
24
39
|
import { Schema as GetProfile } from "./api/getProfile"
|
|
25
40
|
export { Schema as SchemaGetProfile } from "./api/getProfile"
|
|
@@ -49,4 +64,9 @@ export const searchUsers = handleApi({url:"/api/searchUsers",...SearchUsers})
|
|
|
49
64
|
import { Schema as SubmitScore } from "./api/submitScore"
|
|
50
65
|
export { Schema as SchemaSubmitScore } from "./api/submitScore"
|
|
51
66
|
export const submitScore = handleApi({url:"/api/submitScore",...SubmitScore})
|
|
67
|
+
|
|
68
|
+
// ./api/updateBeatmapPage.ts API
|
|
69
|
+
import { Schema as UpdateBeatmapPage } from "./api/updateBeatmapPage"
|
|
70
|
+
export { Schema as SchemaUpdateBeatmapPage } from "./api/updateBeatmapPage"
|
|
71
|
+
export const updateBeatmapPage = handleApi({url:"/api/updateBeatmapPage",...UpdateBeatmapPage})
|
|
52
72
|
export { handleApi } from "./handleApi"
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "rhythia-api",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "107.0.0",
|
|
4
4
|
"main": "index.ts",
|
|
5
5
|
"scripts": {
|
|
6
6
|
"update": "bun ./scripts/update.ts",
|
|
@@ -30,8 +30,9 @@
|
|
|
30
30
|
"isomorphic-git": "^1.27.1",
|
|
31
31
|
"lodash": "^4.17.21",
|
|
32
32
|
"next": "^14.2.5",
|
|
33
|
+
"rhythia-star-calculator": "^1.0.4",
|
|
33
34
|
"simple-git": "^3.25.0",
|
|
34
|
-
"supabase": "^1.
|
|
35
|
+
"supabase": "^1.192.5",
|
|
35
36
|
"tsx": "^4.17.0",
|
|
36
37
|
"utf-8-validate": "^6.0.4",
|
|
37
38
|
"zod": "^3.23.8"
|
package/scripts/test.ts
ADDED
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import { createClient } from "@supabase/supabase-js";
|
|
2
|
+
import { Database } from "../types/database";
|
|
3
|
+
|
|
4
|
+
export const supabase = createClient<Database>(
|
|
5
|
+
`https://pfkajngbllcbdzoylrvp.supabase.co`,
|
|
6
|
+
"eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJzdXBhYmFzZSIsInJlZiI6InBma2FqbmdibGxjYmR6b3lscnZwIiwicm9sZSI6InNlcnZpY2Vfcm9sZSIsImlhdCI6MTcxODU3NjA3MCwiZXhwIjoyMDM0MTUyMDcwfQ.XKUlQWvzmcYyirM-Zi4nwhiEKcpx1xLS97QUyuR3MoY",
|
|
7
|
+
{
|
|
8
|
+
auth: {
|
|
9
|
+
autoRefreshToken: false,
|
|
10
|
+
persistSession: false,
|
|
11
|
+
},
|
|
12
|
+
}
|
|
13
|
+
);
|
|
14
|
+
|
|
15
|
+
async function main() {
|
|
16
|
+
const countQuery = await supabase
|
|
17
|
+
.from("profiles")
|
|
18
|
+
.select("*", { count: "exact", head: true })
|
|
19
|
+
.neq("ban", "excluded");
|
|
20
|
+
|
|
21
|
+
let { data: queryData, error } = await supabase
|
|
22
|
+
.from("profiles")
|
|
23
|
+
.select("*")
|
|
24
|
+
.neq("ban", "excluded")
|
|
25
|
+
.order("skill_points", { ascending: false })
|
|
26
|
+
.range(0, 50);
|
|
27
|
+
|
|
28
|
+
console.log(queryData);
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
main();
|
package/types/database.ts
CHANGED
|
@@ -9,11 +9,49 @@ export type Json =
|
|
|
9
9
|
export type Database = {
|
|
10
10
|
public: {
|
|
11
11
|
Tables: {
|
|
12
|
+
beatmapPages: {
|
|
13
|
+
Row: {
|
|
14
|
+
created_at: string
|
|
15
|
+
id: number
|
|
16
|
+
latestBeatmapHash: string | null
|
|
17
|
+
owner: number | null
|
|
18
|
+
}
|
|
19
|
+
Insert: {
|
|
20
|
+
created_at?: string
|
|
21
|
+
id?: number
|
|
22
|
+
latestBeatmapHash?: string | null
|
|
23
|
+
owner?: number | null
|
|
24
|
+
}
|
|
25
|
+
Update: {
|
|
26
|
+
created_at?: string
|
|
27
|
+
id?: number
|
|
28
|
+
latestBeatmapHash?: string | null
|
|
29
|
+
owner?: number | null
|
|
30
|
+
}
|
|
31
|
+
Relationships: [
|
|
32
|
+
{
|
|
33
|
+
foreignKeyName: "beatmapPages_latestBeatmapHash_fkey"
|
|
34
|
+
columns: ["latestBeatmapHash"]
|
|
35
|
+
isOneToOne: false
|
|
36
|
+
referencedRelation: "beatmaps"
|
|
37
|
+
referencedColumns: ["beatmapHash"]
|
|
38
|
+
},
|
|
39
|
+
{
|
|
40
|
+
foreignKeyName: "beatmapPages_owner_fkey"
|
|
41
|
+
columns: ["owner"]
|
|
42
|
+
isOneToOne: false
|
|
43
|
+
referencedRelation: "profiles"
|
|
44
|
+
referencedColumns: ["id"]
|
|
45
|
+
},
|
|
46
|
+
]
|
|
47
|
+
}
|
|
12
48
|
beatmaps: {
|
|
13
49
|
Row: {
|
|
50
|
+
beatmapFile: string | null
|
|
14
51
|
beatmapHash: string
|
|
15
52
|
created_at: string
|
|
16
53
|
difficulty: number | null
|
|
54
|
+
image: string | null
|
|
17
55
|
length: number | null
|
|
18
56
|
noteCount: number | null
|
|
19
57
|
playcount: number | null
|
|
@@ -21,9 +59,11 @@ export type Database = {
|
|
|
21
59
|
title: string | null
|
|
22
60
|
}
|
|
23
61
|
Insert: {
|
|
62
|
+
beatmapFile?: string | null
|
|
24
63
|
beatmapHash: string
|
|
25
64
|
created_at?: string
|
|
26
65
|
difficulty?: number | null
|
|
66
|
+
image?: string | null
|
|
27
67
|
length?: number | null
|
|
28
68
|
noteCount?: number | null
|
|
29
69
|
playcount?: number | null
|
|
@@ -31,9 +71,11 @@ export type Database = {
|
|
|
31
71
|
title?: string | null
|
|
32
72
|
}
|
|
33
73
|
Update: {
|
|
74
|
+
beatmapFile?: string | null
|
|
34
75
|
beatmapHash?: string
|
|
35
76
|
created_at?: string
|
|
36
77
|
difficulty?: number | null
|
|
78
|
+
image?: string | null
|
|
37
79
|
length?: number | null
|
|
38
80
|
noteCount?: number | null
|
|
39
81
|
playcount?: number | null
|
|
@@ -47,6 +89,8 @@ export type Database = {
|
|
|
47
89
|
about_me: string | null
|
|
48
90
|
avatar_url: string | null
|
|
49
91
|
badges: Json | null
|
|
92
|
+
ban: Database["public"]["Enums"]["banTypes"] | null
|
|
93
|
+
bannedAt: number | null
|
|
50
94
|
computedUsername: string | null
|
|
51
95
|
created_at: number | null
|
|
52
96
|
flag: string | null
|
|
@@ -63,6 +107,8 @@ export type Database = {
|
|
|
63
107
|
about_me?: string | null
|
|
64
108
|
avatar_url?: string | null
|
|
65
109
|
badges?: Json | null
|
|
110
|
+
ban?: Database["public"]["Enums"]["banTypes"] | null
|
|
111
|
+
bannedAt?: number | null
|
|
66
112
|
computedUsername?: string | null
|
|
67
113
|
created_at?: number | null
|
|
68
114
|
flag?: string | null
|
|
@@ -79,6 +125,8 @@ export type Database = {
|
|
|
79
125
|
about_me?: string | null
|
|
80
126
|
avatar_url?: string | null
|
|
81
127
|
badges?: Json | null
|
|
128
|
+
ban?: Database["public"]["Enums"]["banTypes"] | null
|
|
129
|
+
bannedAt?: number | null
|
|
82
130
|
computedUsername?: string | null
|
|
83
131
|
created_at?: number | null
|
|
84
132
|
flag?: string | null
|
|
@@ -160,7 +208,7 @@ export type Database = {
|
|
|
160
208
|
[_ in never]: never
|
|
161
209
|
}
|
|
162
210
|
Enums: {
|
|
163
|
-
|
|
211
|
+
banTypes: "cool" | "silenced" | "restricted" | "excluded"
|
|
164
212
|
}
|
|
165
213
|
CompositeTypes: {
|
|
166
214
|
[_ in never]: never
|