Skip to content

Commit a8ab3ef

Browse files
authored
create context for subsequent supabase operations (new structures) (#187)
1 parent b73c313 commit a8ab3ef

1 file changed

Lines changed: 116 additions & 0 deletions

File tree

Lines changed: 116 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,116 @@
1+
import { getNodeEnv } from "roamjs-components/util/env";
2+
import getCurrentUserEmail from "roamjs-components/queries/getCurrentUserEmail";
3+
import getCurrentUserDisplayName from "roamjs-components/queries/getCurrentUserDisplayName";
4+
import getRoamUrl from "roamjs-components/dom/getRoamUrl";
5+
import { Database } from "@repo/database/types.gen";
6+
7+
type Platform = Database["public"]["Enums"]["Platform"];
8+
9+
export type SupabaseContext = {
10+
platform: Platform;
11+
spaceId: number;
12+
userId: number;
13+
};
14+
15+
let CONTEXT_CACHE: SupabaseContext | null = null;
16+
17+
// TODO: This should be an util on its own.
18+
const base_url =
19+
getNodeEnv() === "development"
20+
? "http://localhost:3000/api/supabase"
21+
: "https://discoursegraphs.com/api/supabase";
22+
23+
// Note: Some of this will be more typesafe if rewritten with direct supabase access eventually.
24+
// We're going through nextjs until we have settled security.
25+
26+
const fetchOrCreateSpaceId = async (): Promise<number> => {
27+
const url = getRoamUrl();
28+
const urlParts = url.split("/");
29+
const name = window.roamAlphaAPI.graph.name;
30+
const platform: Platform = "Roam";
31+
const response = await fetch(base_url + "/space", {
32+
method: "POST",
33+
headers: {
34+
"Content-Type": "application/json",
35+
},
36+
body: JSON.stringify({ url, name, platform }),
37+
});
38+
if (!response.ok)
39+
throw new Error(
40+
`Platform API failed: \${response.status} \${response.statusText}`,
41+
);
42+
const space = await response.json();
43+
if (typeof space.id !== "number") throw new Error("API did not return space");
44+
return space.id;
45+
};
46+
47+
const fetchOrCreatePlatformAccount = async (
48+
{
49+
accountLocalId,
50+
personName,
51+
personEmail
52+
}: {
53+
accountLocalId: string,
54+
personName: string,
55+
personEmail: string | undefined
56+
}): Promise<number> => {
57+
const response = await fetch(
58+
`${base_url}/platform_account`,
59+
{
60+
method: "POST",
61+
headers: {
62+
"Content-Type": "application/json",
63+
},
64+
body: JSON.stringify({
65+
platform: "Roam", account_local_id: accountLocalId, personName
66+
}),
67+
},
68+
);
69+
if (!response.ok)
70+
throw new Error(
71+
`Platform API failed: \${response.status} \${response.statusText}`,
72+
);
73+
const account = await response.json();
74+
if (personEmail !== undefined) {
75+
const idResponse = await fetch(
76+
`${base_url}/agent-identifier`,
77+
{
78+
method: "POST",
79+
headers: {
80+
"Content-Type": "application/json",
81+
},
82+
body: JSON.stringify({
83+
account_id: account.id,
84+
identifier_type: "email",
85+
value: personEmail,
86+
trusted: false, // Roam tests email
87+
}),
88+
},
89+
);
90+
if (!idResponse.ok) {
91+
const error = await idResponse.text();
92+
console.error(`Error setting the email for the account: ${error}`);
93+
// This is not a reason to stop here
94+
}
95+
}
96+
if (typeof account.id !== "number")
97+
throw new Error("API did not return account");
98+
return account.id;
99+
};
100+
101+
export const getSupabaseContext = async (): Promise<SupabaseContext | null> => {
102+
if (CONTEXT_CACHE === null) {
103+
try {
104+
const spaceId = await fetchOrCreateSpaceId();
105+
const accountLocalId = window.roamAlphaAPI.user.uid();
106+
const personEmail = getCurrentUserEmail();
107+
const personName = getCurrentUserDisplayName();
108+
const userId = await fetchOrCreatePlatformAccount({accountLocalId, personName, personEmail});
109+
CONTEXT_CACHE = { platform: "Roam", spaceId, userId };
110+
} catch (error) {
111+
console.error(error);
112+
return null;
113+
}
114+
}
115+
return CONTEXT_CACHE;
116+
};

0 commit comments

Comments
 (0)