improve backend logic

This commit is contained in:
Ishaan Dey 2024-04-21 22:55:49 -04:00
parent e7ca2d0124
commit 14d95eb8fe
12 changed files with 296 additions and 31 deletions

View File

@ -0,0 +1 @@
ALTER TABLE sandbox ADD `init` integer DEFAULT false;

View File

@ -0,0 +1,126 @@
{
"version": "5",
"dialect": "sqlite",
"id": "d6bdd707-d4ac-4a04-9052-aa97d5452e4a",
"prevId": "90f199c9-66a1-4c89-9a19-f7fbd5a35236",
"tables": {
"sandbox": {
"name": "sandbox",
"columns": {
"id": {
"name": "id",
"type": "text",
"primaryKey": true,
"notNull": true,
"autoincrement": false
},
"name": {
"name": "name",
"type": "text",
"primaryKey": false,
"notNull": true,
"autoincrement": false
},
"type": {
"name": "type",
"type": "text",
"primaryKey": false,
"notNull": true,
"autoincrement": false
},
"bucket": {
"name": "bucket",
"type": "text",
"primaryKey": false,
"notNull": false,
"autoincrement": false
},
"init": {
"name": "init",
"type": "integer",
"primaryKey": false,
"notNull": false,
"autoincrement": false,
"default": false
},
"user_id": {
"name": "user_id",
"type": "text",
"primaryKey": false,
"notNull": true,
"autoincrement": false
}
},
"indexes": {
"sandbox_id_unique": {
"name": "sandbox_id_unique",
"columns": [
"id"
],
"isUnique": true
}
},
"foreignKeys": {
"sandbox_user_id_user_id_fk": {
"name": "sandbox_user_id_user_id_fk",
"tableFrom": "sandbox",
"tableTo": "user",
"columnsFrom": [
"user_id"
],
"columnsTo": [
"id"
],
"onDelete": "no action",
"onUpdate": "no action"
}
},
"compositePrimaryKeys": {},
"uniqueConstraints": {}
},
"user": {
"name": "user",
"columns": {
"id": {
"name": "id",
"type": "text",
"primaryKey": true,
"notNull": true,
"autoincrement": false
},
"name": {
"name": "name",
"type": "text",
"primaryKey": false,
"notNull": true,
"autoincrement": false
},
"email": {
"name": "email",
"type": "text",
"primaryKey": false,
"notNull": true,
"autoincrement": false
}
},
"indexes": {
"user_id_unique": {
"name": "user_id_unique",
"columns": [
"id"
],
"isUnique": true
}
},
"foreignKeys": {},
"compositePrimaryKeys": {},
"uniqueConstraints": {}
}
},
"enums": {},
"_meta": {
"schemas": {},
"tables": {},
"columns": {}
}
}

View File

@ -29,6 +29,13 @@
"when": 1713412439820,
"tag": "0003_outgoing_hammerhead",
"breakpoints": true
},
{
"idx": 4,
"version": "5",
"when": 1713753819469,
"tag": "0004_fantastic_venom",
"breakpoints": true
}
]
}

View File

@ -12,6 +12,7 @@
"better-sqlite3": "^9.5.0",
"cross-env": "^7.0.3",
"drizzle-orm": "^0.30.8",
"itty-router": "^5.0.16",
"itty-router-extras": "^0.4.6",
"zod": "^3.22.4"
},
@ -19,7 +20,7 @@
"@cloudflare/vitest-pool-workers": "^0.1.0",
"@cloudflare/workers-types": "^4.20240405.0",
"@types/itty-router-extras": "^0.4.3",
"drizzle-kit": "^0.20.14",
"drizzle-kit": "^0.20.17",
"typescript": "^5.0.4",
"vitest": "1.3.0",
"wrangler": "^3.0.0"
@ -152,15 +153,6 @@
"node": ">=12"
}
},
"node_modules/@drizzle-team/studio": {
"version": "0.0.39",
"resolved": "https://registry.npmjs.org/@drizzle-team/studio/-/studio-0.0.39.tgz",
"integrity": "sha512-c5Hkm7MmQC2n5qAsKShjQrHoqlfGslB8+qWzsGGZ+2dHMRTNG60UuzalF0h0rvBax5uzPXuGkYLGaQ+TUX3yMw==",
"dev": true,
"dependencies": {
"superjson": "^2.2.1"
}
},
"node_modules/@esbuild-kit/core-utils": {
"version": "3.3.2",
"resolved": "https://registry.npmjs.org/@esbuild-kit/core-utils/-/core-utils-3.3.2.tgz",
@ -969,6 +961,25 @@
"node": ">=14"
}
},
"node_modules/@hono/node-server": {
"version": "1.11.0",
"resolved": "https://registry.npmjs.org/@hono/node-server/-/node-server-1.11.0.tgz",
"integrity": "sha512-TLIJq9TMtD1NEG1mVoqNUn1Ita0qSaB5XboZErjFBcO/GJYXwWY4dVdTi9G0lbxtu0x+hJXDItcLaFHb7rlFTw==",
"dev": true,
"engines": {
"node": ">=18.14.1"
}
},
"node_modules/@hono/zod-validator": {
"version": "0.2.1",
"resolved": "https://registry.npmjs.org/@hono/zod-validator/-/zod-validator-0.2.1.tgz",
"integrity": "sha512-HFoxln7Q6JsE64qz2WBS28SD33UB2alp3aRKmcWnNLDzEL1BLsWfbdX6e1HIiUprHYTIXf5y7ax8eYidKUwyaA==",
"dev": true,
"peerDependencies": {
"hono": ">=3.9.0",
"zod": "^3.19.1"
}
},
"node_modules/@jest/schemas": {
"version": "29.6.3",
"resolved": "https://registry.npmjs.org/@jest/schemas/-/schemas-29.6.3.tgz",
@ -1852,13 +1863,14 @@
}
},
"node_modules/drizzle-kit": {
"version": "0.20.14",
"resolved": "https://registry.npmjs.org/drizzle-kit/-/drizzle-kit-0.20.14.tgz",
"integrity": "sha512-0fHv3YIEaUcSVPSGyaaBfOi9bmpajjhbJNdPsRMIUvYdLVxBu9eGjH8mRc3Qk7HVmEidFc/lhG1YyJhoXrn5yA==",
"version": "0.20.17",
"resolved": "https://registry.npmjs.org/drizzle-kit/-/drizzle-kit-0.20.17.tgz",
"integrity": "sha512-mLVDS4nXmO09wFVlzGrdshWnAL+U9eQGC5zRs6hTN6Q9arwQGWU2XnZ17I8BM8Quau8CQRx3Ms6VPgRWJFVp7Q==",
"dev": true,
"dependencies": {
"@drizzle-team/studio": "^0.0.39",
"@esbuild-kit/esm-loader": "^2.5.5",
"@hono/node-server": "^1.9.0",
"@hono/zod-validator": "^0.2.0",
"camelcase": "^7.0.1",
"chalk": "^5.2.0",
"commander": "^9.4.1",
@ -1867,9 +1879,11 @@
"esbuild-register": "^3.5.0",
"glob": "^8.1.0",
"hanji": "^0.0.5",
"hono": "^4.1.4",
"json-diff": "0.9.0",
"minimatch": "^7.4.3",
"semver": "^7.5.4",
"superjson": "^2.2.1",
"zod": "^3.20.2"
},
"bin": {
@ -2798,6 +2812,15 @@
"integrity": "sha512-2bsegYkkHO+h/9MGbn6KWcE45cHZgPANo5LXF7EvWdT0yT2EguSVO1nDgU5c8+ZOPwp2vMNa7YFsJhVcDR9Sdg==",
"dev": true
},
"node_modules/hono": {
"version": "4.2.6",
"resolved": "https://registry.npmjs.org/hono/-/hono-4.2.6.tgz",
"integrity": "sha512-AtbHZJYWsm+uFHLz0C6xltX7hjOV44a55gSEGBfoQOJ00KSxEUOoiIkmd+NXfapNX0j2GCKhqMmYeegBdHRwcQ==",
"dev": true,
"engines": {
"node": ">=16.0.0"
}
},
"node_modules/human-signals": {
"version": "5.0.0",
"resolved": "https://registry.npmjs.org/human-signals/-/human-signals-5.0.0.tgz",
@ -2935,6 +2958,11 @@
"resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz",
"integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw=="
},
"node_modules/itty-router": {
"version": "5.0.16",
"resolved": "https://registry.npmjs.org/itty-router/-/itty-router-5.0.16.tgz",
"integrity": "sha512-Kzk07Cx1dXvwtbCVeLvIT7W9uQaJc3UdWb6L57aSt8usqAWpQJziH3UgSWw2k7up00ImPeNACXY7zHE7eEPd7w=="
},
"node_modules/itty-router-extras": {
"version": "0.4.6",
"resolved": "https://registry.npmjs.org/itty-router-extras/-/itty-router-extras-0.4.6.tgz",

View File

@ -15,7 +15,7 @@
"@cloudflare/vitest-pool-workers": "^0.1.0",
"@cloudflare/workers-types": "^4.20240405.0",
"@types/itty-router-extras": "^0.4.3",
"drizzle-kit": "^0.20.14",
"drizzle-kit": "^0.20.17",
"typescript": "^5.0.4",
"vitest": "1.3.0",
"wrangler": "^3.0.0"
@ -25,6 +25,7 @@
"better-sqlite3": "^9.5.0",
"cross-env": "^7.0.3",
"drizzle-orm": "^0.30.8",
"itty-router": "^5.0.16",
"itty-router-extras": "^0.4.6",
"zod": "^3.22.4"
}

View File

@ -13,6 +13,8 @@ export interface Env {
DB: D1Database;
}
// https://github.com/drizzle-team/drizzle-orm/tree/main/examples/cloudflare-d1
export default {
async fetch(request: Request, env: Env, ctx: ExecutionContext): Promise<Response> {
const url = new URL(request.url);

View File

@ -25,6 +25,7 @@ export const sandbox = sqliteTable("sandbox", {
name: text("name").notNull(),
type: text("type", { enum: ["react", "node"] }).notNull(),
bucket: text("bucket"),
init: integer("init", { mode: "boolean" }).default(false),
userId: text("user_id")
.notNull()
.references(() => user.id),

View File

@ -16,6 +16,7 @@ const express_1 = __importDefault(require("express"));
const dotenv_1 = __importDefault(require("dotenv"));
const http_1 = require("http");
const socket_io_1 = require("socket.io");
const zod_1 = require("zod");
dotenv_1.default.config();
const app = (0, express_1.default)();
const port = process.env.PORT || 4000;
@ -26,24 +27,54 @@ const io = new socket_io_1.Server(httpServer, {
origin: "*",
},
});
const handshakeSchema = zod_1.z.object({
userId: zod_1.z.string(),
sandboxId: zod_1.z.string(),
type: zod_1.z.enum(["node", "react"]),
EIO: zod_1.z.string(),
transport: zod_1.z.string(),
});
io.use((socket, next) => __awaiter(void 0, void 0, void 0, function* () {
const q = socket.handshake.query;
console.log("middleware");
console.log(q);
if (!q.userId || !q.sandboxId) {
const parseQuery = handshakeSchema.safeParse(q);
if (!parseQuery.success) {
console.log("Invalid request.");
next(new Error("Invalid request."));
return;
}
const dbUser = yield fetch(`http://localhost:8787/api/user?id=${q.userId}`);
const dbUserJSON = yield dbUser.json();
if (!dbUserJSON || !dbUserJSON.sandbox.includes(q.sandboxId)) {
const query = parseQuery.data;
const dbUser = yield fetch(`http://localhost:8787/api/user?id=${query.userId}`);
const dbUserJSON = (yield dbUser.json());
console.log("dbUserJSON:", dbUserJSON);
if (!dbUserJSON) {
console.log("DB error.");
next(new Error("DB error."));
return;
}
const sandbox = dbUserJSON.sandbox.find((s) => s.id === query.sandboxId);
if (!sandbox) {
console.log("Invalid credentials.");
next(new Error("Invalid credentials."));
return;
}
const data = {
userId: query.userId,
sandboxId: query.sandboxId,
type: query.type,
init: sandbox.init,
};
socket.data = data;
next();
}));
io.on("connection", (socket) => __awaiter(void 0, void 0, void 0, function* () {
console.log(`connection`);
const userId = socket.handshake.query.userId;
console.log(userId);
const data = socket.data;
console.log("init:", data.init);
if (!data.init) {
// const dbUser = await fetch(
// `http://localhost:8787/sandbox/${data.sandboxId}/init`
// )
}
// socket.emit("loaded", {
// rootContent: await fetchDir("/workspace", "")
// });

3
backend/server/dist/types.js vendored Normal file
View File

@ -0,0 +1,3 @@
"use strict";
// DB Types
Object.defineProperty(exports, "__esModule", { value: true });

View File

@ -4,6 +4,7 @@ import { createServer } from "http"
import { Server } from "socket.io"
import { z } from "zod"
import { User } from "./types"
dotenv.config()
@ -17,31 +18,77 @@ const io = new Server(httpServer, {
},
})
const handshakeSchema = z.object({
userId: z.string(),
sandboxId: z.string(),
type: z.enum(["node", "react"]),
EIO: z.string(),
transport: z.string(),
})
io.use(async (socket, next) => {
const q = socket.handshake.query
console.log("middleware")
console.log(q)
if (!q.userId || !q.sandboxId) {
const parseQuery = handshakeSchema.safeParse(q)
if (!parseQuery.success) {
console.log("Invalid request.")
next(new Error("Invalid request."))
return
}
const dbUser = await fetch(`http://localhost:8787/api/user?id=${q.userId}`)
const dbUserJSON = await dbUser.json()
const query = parseQuery.data
if (!dbUserJSON || !dbUserJSON.sandbox.includes(q.sandboxId)) {
const dbUser = await fetch(
`http://localhost:8787/api/user?id=${query.userId}`
)
const dbUserJSON = (await dbUser.json()) as User
console.log("dbUserJSON:", dbUserJSON)
if (!dbUserJSON) {
console.log("DB error.")
next(new Error("DB error."))
return
}
const sandbox = dbUserJSON.sandbox.find((s) => s.id === query.sandboxId)
if (!sandbox) {
console.log("Invalid credentials.")
next(new Error("Invalid credentials."))
return
}
const data = {
userId: query.userId,
sandboxId: query.sandboxId,
type: query.type,
init: sandbox.init,
}
socket.data = data
next()
})
io.on("connection", async (socket) => {
console.log(`connection`)
const userId = socket.handshake.query.userId
const data = socket.data as {
userId: string
sandboxId: string
type: "node" | "react"
init: boolean
}
console.log(userId)
console.log("init:", data.init)
if (!data.init) {
// const dbUser = await fetch(
// `http://localhost:8787/sandbox/${data.sandboxId}/init`
// )
}
// socket.emit("loaded", {
// rootContent: await fetchDir("/workspace", "")

View File

@ -0,0 +1,17 @@
// DB Types
export type User = {
id: string
name: string
email: string
sandbox: Sandbox[]
}
export type Sandbox = {
id: string
name: string
type: "react" | "node"
init: boolean
bucket: string | null
userId: string
}

View File

@ -11,6 +11,7 @@ export type Sandbox = {
id: string
name: string
type: "react" | "node"
init: boolean
bucket: string | null
userId: string
}