Mid-Simulator/helper.ts
2022-04-18 01:14:39 +00:00

150 lines
3.2 KiB
TypeScript

import StackTrace from "stacktrace-js";
// report error to server
window.addEventListener("error", (e) => {
StackTrace
.fromError(e.error)
.then((stack) => {
fetch("/error", {
method: "POST",
headers: {
"Content-Type": "application/json",
},
body: JSON.stringify({
msg: e.error.message,
stack: stack.slice(0, 4).map((step) => {
return {
...step,
file: step.fileName.replace(location.origin + "/", ""),
line: step.lineNumber,
col: step.columnNumber,
};
}),
}),
});
})
.catch(() => console.error("failed to parse err"));
});
interface User {
id: string,
name: string,
}
interface Replit {
getUser(): Promise<User | null>,
auth(): Promise<User | null>,
getUserOrAuth(): Promise<User | null>,
getData<D = any>(key: string, def?: D): Promise<D>,
setData<D>(key: string, val: D): Promise<D>,
delData(key: string): Promise<void>,
listData(): Promise<string[]>,
clearData(): Promise<void>,
}
declare global {
const replit: Replit;
}
// replit auth & db integration
const replit: Replit = {
getUser(): Promise<User | null> {
return fetch("/user")
.then((res) => res.json())
.then((user) => {
if (user) {
return Promise.resolve(user);
} else {
return Promise.resolve(null);
}
});
},
auth(): Promise<User | null> {
return new Promise((resolve, reject) => {
const authComplete = (e) => {
if (e.data !== "auth_complete") {
resolve(null);
return;
}
window.removeEventListener("message", authComplete);
authWindow.close();
this.getUser().then(resolve);
};
window.addEventListener("message", authComplete);
const w = 320;
const h = 480;
const left = (screen.width / 2) - (w / 2);
const top = (screen.height / 2) - (h / 2);
const authWindow = window.open(
`https://repl.it/auth_with_repl_site?domain=${location.host}`,
"_blank",
`modal=yes, toolbar=no, location=no, directories=no, status=no, menubar=no, scrollbars=no, resizable=no, copyhistory=no, width=${w}, height=${h}, top=${top}, left=${left}`
);
});
},
getUserOrAuth(): Promise<User | null> {
return new Promise((resolve, reject) => {
this.getUser().then((user) => {
if (user) {
resolve(user);
} else {
this.auth().then((user) => {
resolve(user);
})
}
})
});
},
getData<D = any>(key: string, def?: D): Promise<D> {
return fetch(`/db/${key}`)
.then((res) => res.json())
.then((val) => {
// set default value if empty
if (val == null && def !== undefined) {
return this.setData(key, def);
}
return Promise.resolve(val);
});
},
setData<D>(key: string, val: D): Promise<D> {
return fetch(`/db/${key}`, {
method: "POST",
headers: {
"Content-Type": "application/json",
},
body: JSON.stringify(val),
}).then(() => Promise.resolve(val));
},
delData(key: string): Promise<void> {
return fetch(`/db/${key}`, {
method: "DELETE",
}).then(() => {});
},
listData(): Promise<string[]> {
return fetch(`/db`)
.then((res) => res.json());
},
clearData(): Promise<void> {
return fetch(`/db`, {
method: "DELETE",
}).then((res) => {});
},
};
window.replit = replit;