rhythia-api 66.0.0 → 68.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.
@@ -1,22 +1,47 @@
1
+ import { NextResponse } from "next/server";
1
2
  import z from "zod";
3
+ import { Database } from "../types/database";
4
+ import { protectedApi, validUser } from "../utils/requestUtils";
5
+ import { supabase } from "../utils/supabase";
2
6
 
3
7
  export const Schema = {
4
8
  input: z.object({
5
- name: z.string(),
6
- age: z.number(),
9
+ session: z.string(),
10
+ data: z.object({
11
+ avatar_url: z.string().optional(),
12
+ about_me: z.string().optional(),
13
+ username: z.string().optional(),
14
+ }),
7
15
  }),
8
16
  output: z.object({
9
- uid: z.string(),
17
+ error: z.string().optional(),
10
18
  }),
11
19
  };
12
20
 
13
- export async function GET(
14
- res: Response
15
- ): Promise<(typeof Schema)["output"]["_type"]> {
16
- const toParse = await res.json();
17
- const data = Schema.input.parse(toParse);
21
+ export async function POST(res: Response): Promise<NextResponse> {
22
+ return protectedApi({
23
+ response: res,
24
+ schema: Schema,
25
+ authorization: validUser,
26
+ activity: handler,
27
+ });
28
+ }
29
+
30
+ async function handler(
31
+ data: (typeof Schema)["input"]["_type"]
32
+ ): Promise<NextResponse<(typeof Schema)["output"]["_type"]>> {
33
+ const user = (await supabase.auth.getUser(data.session)).data.user!;
18
34
 
19
- return {
20
- uid: data.name,
35
+ const upsertPayload: Database["public"]["Tables"]["profiles"]["Update"] = {
36
+ uid: user.id,
37
+ flag: "",
38
+ ...data.data,
21
39
  };
40
+
41
+ const upsertResult = await supabase
42
+ .from("profiles")
43
+ .upsert(upsertPayload)
44
+ .select();
45
+
46
+ return NextResponse.json({});
22
47
  }
package/api/getProfile.ts CHANGED
@@ -1,9 +1,13 @@
1
+ import { NOT_FOUND } from "http-status";
2
+ import { NextResponse } from "next/server";
1
3
  import z from "zod";
4
+ import { protectedApi, validUser } from "../utils/requestUtils";
2
5
  import { supabase } from "../utils/supabase";
3
6
 
4
7
  export const Schema = {
5
8
  input: z.object({
6
- id: z.string(),
9
+ session: z.string(),
10
+ id: z.number(),
7
11
  }),
8
12
  output: z.object({
9
13
  error: z.string().optional(),
@@ -23,27 +27,38 @@ export const Schema = {
23
27
  }),
24
28
  };
25
29
 
26
- export async function POST(
27
- res: Response
28
- ): Promise<(typeof Schema)["output"]["_type"]> {
29
- const toParse = await res.json();
30
- const data = Schema.input.parse(toParse);
30
+ export async function POST(res: Response): Promise<NextResponse> {
31
+ return protectedApi({
32
+ response: res,
33
+ schema: Schema,
34
+ authorization: validUser,
35
+ activity: handler,
36
+ });
37
+ }
31
38
 
39
+ async function handler(
40
+ data: (typeof Schema)["input"]["_type"]
41
+ ): Promise<NextResponse<(typeof Schema)["output"]["_type"]>> {
32
42
  let { data: profiles, error } = await supabase
33
43
  .from("profiles")
34
44
  .select("*")
35
- .eq("column", data.id);
45
+ .eq("id", data.id);
46
+
47
+ console.log(profiles, error);
36
48
 
37
49
  if (!profiles?.length) {
38
- return {
39
- error: "User not found",
40
- };
50
+ return NextResponse.json(
51
+ {
52
+ error: "User not found",
53
+ },
54
+ { status: NOT_FOUND }
55
+ );
41
56
  }
42
57
 
43
58
  const user = profiles[0];
44
- return {
59
+ return NextResponse.json({
45
60
  user: {
46
61
  ...user,
47
62
  },
48
- };
63
+ });
49
64
  }
@@ -1,5 +1,5 @@
1
1
  import { createClient } from "@supabase/supabase-js";
2
- import { Database } from "../types/supabase";
2
+ import { Database } from "../types/database";
3
3
 
4
4
  const adminClient = createClient<Database>(
5
5
  `https://pfkajngbllcbdzoylrvp.supabase.co`,
package/package.json CHANGED
@@ -1,16 +1,19 @@
1
1
  {
2
2
  "name": "rhythia-api",
3
- "version": "66.0.0",
3
+ "version": "68.0.0",
4
4
  "main": "index.ts",
5
5
  "scripts": {
6
6
  "update": "bun ./scripts/update.ts",
7
7
  "ci-deploy": "tsx ./scripts/ci-deploy.ts",
8
8
  "test": "bun ./scripts/test.ts",
9
- "sync": "npx supabase gen types typescript --project-id \"pfkajngbllcbdzoylrvp\" --schema public > types/supabase.ts",
9
+ "sync": "npx supabase gen types typescript --project-id \"pfkajngbllcbdzoylrvp\" --schema public > types/database.ts",
10
10
  "pipeline:build-api": "tsx ./scripts/build.ts",
11
11
  "pipeline:deploy-testing": "tsx ./scripts/build.ts"
12
12
  },
13
13
  "license": "MIT",
14
+ "devDependencies": {
15
+ "next": "^14.2.5"
16
+ },
14
17
  "dependencies": {
15
18
  "@netlify/zip-it-and-ship-it": "^9.37.9",
16
19
  "@supabase/supabase-js": "^2.45.1",
@@ -18,14 +21,16 @@
18
21
  "@types/bun": "^1.1.6",
19
22
  "@types/lodash": "^4.17.7",
20
23
  "@types/node": "^22.2.0",
24
+ "@vercel/node": "^3.2.8",
21
25
  "aws-lambda": "^1.0.7",
22
26
  "bufferutil": "^4.0.8",
23
27
  "bun": "^1.1.22",
24
28
  "esbuild": "^0.23.0",
29
+ "http-status": "^1.7.4",
25
30
  "isomorphic-git": "^1.27.1",
26
31
  "lodash": "^4.17.21",
27
32
  "simple-git": "^3.25.0",
28
- "supabase": "^1.188.4",
33
+ "supabase": "^1.190.0",
29
34
  "tsx": "^4.17.0",
30
35
  "utf-8-validate": "^6.0.4",
31
36
  "zod": "^3.23.8"
package/scripts/test.ts CHANGED
@@ -3,7 +3,7 @@ const res = await fetch("https://development.rhythia.com/api/getProfile", {
3
3
  headers: {
4
4
  "Content-Type": "application/json",
5
5
  },
6
- body: JSON.stringify({ id: 0 }),
6
+ body: JSON.stringify({ id: 0, session: "asd" }),
7
7
  });
8
8
 
9
9
  console.log(await res.text());
@@ -0,0 +1,55 @@
1
+ import status, { INTERNAL_SERVER_ERROR, UNAUTHORIZED } from "http-status";
2
+ import { NextResponse } from "next/server";
3
+ import { supabase } from "./supabase";
4
+
5
+ export async function protectedApi({
6
+ response,
7
+ schema,
8
+ authorization,
9
+ activity,
10
+ }: {
11
+ response: Response;
12
+ schema: { input: Zod.ZodObject<any>; output: Zod.ZodObject<any> };
13
+ authorization: Function;
14
+ activity: Function;
15
+ }) {
16
+ let data;
17
+
18
+ try {
19
+ const toParse = await response.json();
20
+ data = schema.input.parse(toParse);
21
+ } catch (error) {
22
+ return NextResponse.json(
23
+ { error: error.toString() },
24
+ { status: status.BAD_REQUEST }
25
+ );
26
+ }
27
+
28
+ const authorizationReponse = await authorization(data);
29
+ if (authorizationReponse) {
30
+ return authorizationReponse;
31
+ }
32
+
33
+ return await activity(data);
34
+ }
35
+
36
+ export async function validUser(data) {
37
+ if (!data.session) {
38
+ return NextResponse.json(
39
+ {
40
+ error: "Session is missing",
41
+ },
42
+ { status: INTERNAL_SERVER_ERROR }
43
+ );
44
+ }
45
+
46
+ const user = await supabase.auth.getUser(data.session);
47
+ if (!user.error || !user.data.user) {
48
+ return NextResponse.json(
49
+ {
50
+ error: "Invalid user session",
51
+ },
52
+ { status: UNAUTHORIZED }
53
+ );
54
+ }
55
+ }
package/utils/supabase.ts CHANGED
@@ -1,5 +1,5 @@
1
1
  import { createClient } from "@supabase/supabase-js";
2
- import { Database } from "../types/supabase";
2
+ import { Database } from "../types/database";
3
3
 
4
4
  export const supabase = createClient<Database>(
5
5
  `https://pfkajngbllcbdzoylrvp.supabase.co`,
File without changes