Compare commits
3 Commits
e2b-test
...
fix-multip
Author | SHA1 | Date | |
---|---|---|---|
95a92bbc4c | |||
d28c0cbea6 | |||
bd33eb9b1c |
@ -1,19 +0,0 @@
|
|||||||
# e2b template build --name "terminal"
|
|
||||||
|
|
||||||
# Use a Debian-based base image
|
|
||||||
FROM ubuntu:22.04
|
|
||||||
|
|
||||||
# Install dependencies and customize sandbox
|
|
||||||
RUN apt update \
|
|
||||||
&& apt install -y sudo
|
|
||||||
|
|
||||||
# Install xterm
|
|
||||||
RUN apt update \
|
|
||||||
&& apt install -y xterm
|
|
||||||
|
|
||||||
RUN apt update \
|
|
||||||
&& apt install -y tmux screen
|
|
||||||
|
|
||||||
# Clean up
|
|
||||||
RUN apt clean \
|
|
||||||
&& rm -rf /var/lib/apt/lists/*
|
|
@ -1,14 +0,0 @@
|
|||||||
# This is a config for E2B sandbox template.
|
|
||||||
# You can use 'template_id' (ne8xtb57tq5xw9vwhdyc) or 'template_name (terminal) from this config to spawn a sandbox:
|
|
||||||
|
|
||||||
# Python SDK
|
|
||||||
# from e2b import Sandbox
|
|
||||||
# sandbox = Sandbox(template='terminal')
|
|
||||||
|
|
||||||
# JS SDK
|
|
||||||
# import { Sandbox } from 'e2b'
|
|
||||||
# const sandbox = await Sandbox.create({ template: 'terminal' })
|
|
||||||
|
|
||||||
dockerfile = "e2b.Dockerfile"
|
|
||||||
template_name = "terminal"
|
|
||||||
template_id = "ne8xtb57tq5xw9vwhdyc"
|
|
@ -1,168 +1,197 @@
|
|||||||
{
|
{
|
||||||
"version": "5",
|
"version": "5",
|
||||||
"dialect": "sqlite",
|
"dialect": "sqlite",
|
||||||
"id": "6570ba20-a672-400c-8147-7ba533784918",
|
"id": "70e3d022-aed8-4464-9063-c92113b4ebe2",
|
||||||
"prevId": "00000000-0000-0000-0000-000000000000",
|
"prevId": "00000000-0000-0000-0000-000000000000",
|
||||||
"tables": {
|
"tables": {
|
||||||
"sandbox": {
|
"sandbox": {
|
||||||
"name": "sandbox",
|
"name": "sandbox",
|
||||||
"columns": {
|
"columns": {
|
||||||
"id": {
|
"id": {
|
||||||
"name": "id",
|
"name": "id",
|
||||||
"type": "text",
|
"type": "text",
|
||||||
"primaryKey": true,
|
"primaryKey": true,
|
||||||
"notNull": true,
|
"notNull": true,
|
||||||
"autoincrement": false
|
"autoincrement": false
|
||||||
|
},
|
||||||
|
"name": {
|
||||||
|
"name": "name",
|
||||||
|
"type": "text",
|
||||||
|
"primaryKey": false,
|
||||||
|
"notNull": true,
|
||||||
|
"autoincrement": false
|
||||||
|
},
|
||||||
|
"type": {
|
||||||
|
"name": "type",
|
||||||
|
"type": "text",
|
||||||
|
"primaryKey": false,
|
||||||
|
"notNull": true,
|
||||||
|
"autoincrement": false
|
||||||
|
},
|
||||||
|
"visibility": {
|
||||||
|
"name": "visibility",
|
||||||
|
"type": "text",
|
||||||
|
"primaryKey": false,
|
||||||
|
"notNull": false,
|
||||||
|
"autoincrement": false
|
||||||
|
},
|
||||||
|
"createdAt": {
|
||||||
|
"name": "createdAt",
|
||||||
|
"type": "integer",
|
||||||
|
"primaryKey": false,
|
||||||
|
"notNull": false,
|
||||||
|
"autoincrement": false
|
||||||
|
},
|
||||||
|
"user_id": {
|
||||||
|
"name": "user_id",
|
||||||
|
"type": "text",
|
||||||
|
"primaryKey": false,
|
||||||
|
"notNull": true,
|
||||||
|
"autoincrement": false
|
||||||
|
}
|
||||||
},
|
},
|
||||||
"name": {
|
"indexes": {
|
||||||
"name": "name",
|
"sandbox_id_unique": {
|
||||||
"type": "text",
|
"name": "sandbox_id_unique",
|
||||||
"primaryKey": false,
|
"columns": [
|
||||||
"notNull": true,
|
"id"
|
||||||
"autoincrement": false
|
],
|
||||||
|
"isUnique": true
|
||||||
|
}
|
||||||
},
|
},
|
||||||
"type": {
|
"foreignKeys": {
|
||||||
"name": "type",
|
"sandbox_user_id_user_id_fk": {
|
||||||
"type": "text",
|
"name": "sandbox_user_id_user_id_fk",
|
||||||
"primaryKey": false,
|
"tableFrom": "sandbox",
|
||||||
"notNull": true,
|
"tableTo": "user",
|
||||||
"autoincrement": false
|
"columnsFrom": [
|
||||||
|
"user_id"
|
||||||
|
],
|
||||||
|
"columnsTo": [
|
||||||
|
"id"
|
||||||
|
],
|
||||||
|
"onDelete": "no action",
|
||||||
|
"onUpdate": "no action"
|
||||||
|
}
|
||||||
},
|
},
|
||||||
"visibility": {
|
"compositePrimaryKeys": {},
|
||||||
"name": "visibility",
|
"uniqueConstraints": {}
|
||||||
"type": "text",
|
|
||||||
"primaryKey": false,
|
|
||||||
"notNull": false,
|
|
||||||
"autoincrement": false
|
|
||||||
},
|
|
||||||
"user_id": {
|
|
||||||
"name": "user_id",
|
|
||||||
"type": "text",
|
|
||||||
"primaryKey": false,
|
|
||||||
"notNull": true,
|
|
||||||
"autoincrement": false
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
"indexes": {
|
"user": {
|
||||||
"sandbox_id_unique": {
|
"name": "user",
|
||||||
"name": "sandbox_id_unique",
|
"columns": {
|
||||||
"columns": [
|
"id": {
|
||||||
"id"
|
"name": "id",
|
||||||
],
|
"type": "text",
|
||||||
"isUnique": true
|
"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
|
||||||
|
},
|
||||||
|
"image": {
|
||||||
|
"name": "image",
|
||||||
|
"type": "text",
|
||||||
|
"primaryKey": false,
|
||||||
|
"notNull": false,
|
||||||
|
"autoincrement": false
|
||||||
|
},
|
||||||
|
"generations": {
|
||||||
|
"name": "generations",
|
||||||
|
"type": "integer",
|
||||||
|
"primaryKey": false,
|
||||||
|
"notNull": false,
|
||||||
|
"autoincrement": false,
|
||||||
|
"default": 0
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"indexes": {
|
||||||
|
"user_id_unique": {
|
||||||
|
"name": "user_id_unique",
|
||||||
|
"columns": [
|
||||||
|
"id"
|
||||||
|
],
|
||||||
|
"isUnique": true
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"foreignKeys": {},
|
||||||
|
"compositePrimaryKeys": {},
|
||||||
|
"uniqueConstraints": {}
|
||||||
},
|
},
|
||||||
"foreignKeys": {
|
"users_to_sandboxes": {
|
||||||
"sandbox_user_id_user_id_fk": {
|
"name": "users_to_sandboxes",
|
||||||
"name": "sandbox_user_id_user_id_fk",
|
"columns": {
|
||||||
"tableFrom": "sandbox",
|
"userId": {
|
||||||
"tableTo": "user",
|
"name": "userId",
|
||||||
"columnsFrom": [
|
"type": "text",
|
||||||
"user_id"
|
"primaryKey": false,
|
||||||
],
|
"notNull": true,
|
||||||
"columnsTo": [
|
"autoincrement": false
|
||||||
"id"
|
},
|
||||||
],
|
"sandboxId": {
|
||||||
"onDelete": "no action",
|
"name": "sandboxId",
|
||||||
"onUpdate": "no action"
|
"type": "text",
|
||||||
}
|
"primaryKey": false,
|
||||||
},
|
"notNull": true,
|
||||||
"compositePrimaryKeys": {},
|
"autoincrement": false
|
||||||
"uniqueConstraints": {}
|
},
|
||||||
|
"sharedOn": {
|
||||||
|
"name": "sharedOn",
|
||||||
|
"type": "integer",
|
||||||
|
"primaryKey": false,
|
||||||
|
"notNull": false,
|
||||||
|
"autoincrement": false
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"indexes": {},
|
||||||
|
"foreignKeys": {
|
||||||
|
"users_to_sandboxes_userId_user_id_fk": {
|
||||||
|
"name": "users_to_sandboxes_userId_user_id_fk",
|
||||||
|
"tableFrom": "users_to_sandboxes",
|
||||||
|
"tableTo": "user",
|
||||||
|
"columnsFrom": [
|
||||||
|
"userId"
|
||||||
|
],
|
||||||
|
"columnsTo": [
|
||||||
|
"id"
|
||||||
|
],
|
||||||
|
"onDelete": "no action",
|
||||||
|
"onUpdate": "no action"
|
||||||
|
},
|
||||||
|
"users_to_sandboxes_sandboxId_sandbox_id_fk": {
|
||||||
|
"name": "users_to_sandboxes_sandboxId_sandbox_id_fk",
|
||||||
|
"tableFrom": "users_to_sandboxes",
|
||||||
|
"tableTo": "sandbox",
|
||||||
|
"columnsFrom": [
|
||||||
|
"sandboxId"
|
||||||
|
],
|
||||||
|
"columnsTo": [
|
||||||
|
"id"
|
||||||
|
],
|
||||||
|
"onDelete": "no action",
|
||||||
|
"onUpdate": "no action"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"compositePrimaryKeys": {},
|
||||||
|
"uniqueConstraints": {}
|
||||||
|
}
|
||||||
},
|
},
|
||||||
"user": {
|
"enums": {},
|
||||||
"name": "user",
|
"_meta": {
|
||||||
"columns": {
|
"schemas": {},
|
||||||
"id": {
|
"tables": {},
|
||||||
"name": "id",
|
"columns": {}
|
||||||
"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": {}
|
|
||||||
},
|
|
||||||
"users_to_sandboxes": {
|
|
||||||
"name": "users_to_sandboxes",
|
|
||||||
"columns": {
|
|
||||||
"userId": {
|
|
||||||
"name": "userId",
|
|
||||||
"type": "text",
|
|
||||||
"primaryKey": false,
|
|
||||||
"notNull": true,
|
|
||||||
"autoincrement": false
|
|
||||||
},
|
|
||||||
"sandboxId": {
|
|
||||||
"name": "sandboxId",
|
|
||||||
"type": "text",
|
|
||||||
"primaryKey": false,
|
|
||||||
"notNull": true,
|
|
||||||
"autoincrement": false
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"indexes": {},
|
|
||||||
"foreignKeys": {
|
|
||||||
"users_to_sandboxes_userId_user_id_fk": {
|
|
||||||
"name": "users_to_sandboxes_userId_user_id_fk",
|
|
||||||
"tableFrom": "users_to_sandboxes",
|
|
||||||
"tableTo": "user",
|
|
||||||
"columnsFrom": [
|
|
||||||
"userId"
|
|
||||||
],
|
|
||||||
"columnsTo": [
|
|
||||||
"id"
|
|
||||||
],
|
|
||||||
"onDelete": "no action",
|
|
||||||
"onUpdate": "no action"
|
|
||||||
},
|
|
||||||
"users_to_sandboxes_sandboxId_sandbox_id_fk": {
|
|
||||||
"name": "users_to_sandboxes_sandboxId_sandbox_id_fk",
|
|
||||||
"tableFrom": "users_to_sandboxes",
|
|
||||||
"tableTo": "sandbox",
|
|
||||||
"columnsFrom": [
|
|
||||||
"sandboxId"
|
|
||||||
],
|
|
||||||
"columnsTo": [
|
|
||||||
"id"
|
|
||||||
],
|
|
||||||
"onDelete": "no action",
|
|
||||||
"onUpdate": "no action"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"compositePrimaryKeys": {},
|
|
||||||
"uniqueConstraints": {}
|
|
||||||
}
|
}
|
||||||
},
|
|
||||||
"enums": {},
|
|
||||||
"_meta": {
|
|
||||||
"schemas": {},
|
|
||||||
"tables": {},
|
|
||||||
"columns": {}
|
|
||||||
}
|
}
|
||||||
}
|
|
@ -1,175 +0,0 @@
|
|||||||
{
|
|
||||||
"version": "5",
|
|
||||||
"dialect": "sqlite",
|
|
||||||
"id": "9f64104a-4954-40c0-8155-17755ea0a243",
|
|
||||||
"prevId": "6570ba20-a672-400c-8147-7ba533784918",
|
|
||||||
"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
|
|
||||||
},
|
|
||||||
"visibility": {
|
|
||||||
"name": "visibility",
|
|
||||||
"type": "text",
|
|
||||||
"primaryKey": false,
|
|
||||||
"notNull": false,
|
|
||||||
"autoincrement": 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
|
|
||||||
},
|
|
||||||
"image": {
|
|
||||||
"name": "image",
|
|
||||||
"type": "text",
|
|
||||||
"primaryKey": false,
|
|
||||||
"notNull": false,
|
|
||||||
"autoincrement": false
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"indexes": {
|
|
||||||
"user_id_unique": {
|
|
||||||
"name": "user_id_unique",
|
|
||||||
"columns": [
|
|
||||||
"id"
|
|
||||||
],
|
|
||||||
"isUnique": true
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"foreignKeys": {},
|
|
||||||
"compositePrimaryKeys": {},
|
|
||||||
"uniqueConstraints": {}
|
|
||||||
},
|
|
||||||
"users_to_sandboxes": {
|
|
||||||
"name": "users_to_sandboxes",
|
|
||||||
"columns": {
|
|
||||||
"userId": {
|
|
||||||
"name": "userId",
|
|
||||||
"type": "text",
|
|
||||||
"primaryKey": false,
|
|
||||||
"notNull": true,
|
|
||||||
"autoincrement": false
|
|
||||||
},
|
|
||||||
"sandboxId": {
|
|
||||||
"name": "sandboxId",
|
|
||||||
"type": "text",
|
|
||||||
"primaryKey": false,
|
|
||||||
"notNull": true,
|
|
||||||
"autoincrement": false
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"indexes": {},
|
|
||||||
"foreignKeys": {
|
|
||||||
"users_to_sandboxes_userId_user_id_fk": {
|
|
||||||
"name": "users_to_sandboxes_userId_user_id_fk",
|
|
||||||
"tableFrom": "users_to_sandboxes",
|
|
||||||
"tableTo": "user",
|
|
||||||
"columnsFrom": [
|
|
||||||
"userId"
|
|
||||||
],
|
|
||||||
"columnsTo": [
|
|
||||||
"id"
|
|
||||||
],
|
|
||||||
"onDelete": "no action",
|
|
||||||
"onUpdate": "no action"
|
|
||||||
},
|
|
||||||
"users_to_sandboxes_sandboxId_sandbox_id_fk": {
|
|
||||||
"name": "users_to_sandboxes_sandboxId_sandbox_id_fk",
|
|
||||||
"tableFrom": "users_to_sandboxes",
|
|
||||||
"tableTo": "sandbox",
|
|
||||||
"columnsFrom": [
|
|
||||||
"sandboxId"
|
|
||||||
],
|
|
||||||
"columnsTo": [
|
|
||||||
"id"
|
|
||||||
],
|
|
||||||
"onDelete": "no action",
|
|
||||||
"onUpdate": "no action"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"compositePrimaryKeys": {},
|
|
||||||
"uniqueConstraints": {}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"enums": {},
|
|
||||||
"_meta": {
|
|
||||||
"schemas": {},
|
|
||||||
"tables": {},
|
|
||||||
"columns": {}
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,168 +0,0 @@
|
|||||||
{
|
|
||||||
"version": "5",
|
|
||||||
"dialect": "sqlite",
|
|
||||||
"id": "5baf10d6-7697-42ba-a11a-ee4c7bd7e91e",
|
|
||||||
"prevId": "9f64104a-4954-40c0-8155-17755ea0a243",
|
|
||||||
"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
|
|
||||||
},
|
|
||||||
"visibility": {
|
|
||||||
"name": "visibility",
|
|
||||||
"type": "text",
|
|
||||||
"primaryKey": false,
|
|
||||||
"notNull": false,
|
|
||||||
"autoincrement": 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": {}
|
|
||||||
},
|
|
||||||
"users_to_sandboxes": {
|
|
||||||
"name": "users_to_sandboxes",
|
|
||||||
"columns": {
|
|
||||||
"userId": {
|
|
||||||
"name": "userId",
|
|
||||||
"type": "text",
|
|
||||||
"primaryKey": false,
|
|
||||||
"notNull": true,
|
|
||||||
"autoincrement": false
|
|
||||||
},
|
|
||||||
"sandboxId": {
|
|
||||||
"name": "sandboxId",
|
|
||||||
"type": "text",
|
|
||||||
"primaryKey": false,
|
|
||||||
"notNull": true,
|
|
||||||
"autoincrement": false
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"indexes": {},
|
|
||||||
"foreignKeys": {
|
|
||||||
"users_to_sandboxes_userId_user_id_fk": {
|
|
||||||
"name": "users_to_sandboxes_userId_user_id_fk",
|
|
||||||
"tableFrom": "users_to_sandboxes",
|
|
||||||
"tableTo": "user",
|
|
||||||
"columnsFrom": [
|
|
||||||
"userId"
|
|
||||||
],
|
|
||||||
"columnsTo": [
|
|
||||||
"id"
|
|
||||||
],
|
|
||||||
"onDelete": "no action",
|
|
||||||
"onUpdate": "no action"
|
|
||||||
},
|
|
||||||
"users_to_sandboxes_sandboxId_sandbox_id_fk": {
|
|
||||||
"name": "users_to_sandboxes_sandboxId_sandbox_id_fk",
|
|
||||||
"tableFrom": "users_to_sandboxes",
|
|
||||||
"tableTo": "sandbox",
|
|
||||||
"columnsFrom": [
|
|
||||||
"sandboxId"
|
|
||||||
],
|
|
||||||
"columnsTo": [
|
|
||||||
"id"
|
|
||||||
],
|
|
||||||
"onDelete": "no action",
|
|
||||||
"onUpdate": "no action"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"compositePrimaryKeys": {},
|
|
||||||
"uniqueConstraints": {}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"enums": {},
|
|
||||||
"_meta": {
|
|
||||||
"schemas": {},
|
|
||||||
"tables": {},
|
|
||||||
"columns": {}
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,175 +0,0 @@
|
|||||||
{
|
|
||||||
"version": "5",
|
|
||||||
"dialect": "sqlite",
|
|
||||||
"id": "37e38b82-1494-4818-8c26-b9024cce3fa9",
|
|
||||||
"prevId": "5baf10d6-7697-42ba-a11a-ee4c7bd7e91e",
|
|
||||||
"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
|
|
||||||
},
|
|
||||||
"visibility": {
|
|
||||||
"name": "visibility",
|
|
||||||
"type": "text",
|
|
||||||
"primaryKey": false,
|
|
||||||
"notNull": false,
|
|
||||||
"autoincrement": 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
|
|
||||||
},
|
|
||||||
"image": {
|
|
||||||
"name": "image",
|
|
||||||
"type": "text",
|
|
||||||
"primaryKey": false,
|
|
||||||
"notNull": false,
|
|
||||||
"autoincrement": false
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"indexes": {
|
|
||||||
"user_id_unique": {
|
|
||||||
"name": "user_id_unique",
|
|
||||||
"columns": [
|
|
||||||
"id"
|
|
||||||
],
|
|
||||||
"isUnique": true
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"foreignKeys": {},
|
|
||||||
"compositePrimaryKeys": {},
|
|
||||||
"uniqueConstraints": {}
|
|
||||||
},
|
|
||||||
"users_to_sandboxes": {
|
|
||||||
"name": "users_to_sandboxes",
|
|
||||||
"columns": {
|
|
||||||
"userId": {
|
|
||||||
"name": "userId",
|
|
||||||
"type": "text",
|
|
||||||
"primaryKey": false,
|
|
||||||
"notNull": true,
|
|
||||||
"autoincrement": false
|
|
||||||
},
|
|
||||||
"sandboxId": {
|
|
||||||
"name": "sandboxId",
|
|
||||||
"type": "text",
|
|
||||||
"primaryKey": false,
|
|
||||||
"notNull": true,
|
|
||||||
"autoincrement": false
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"indexes": {},
|
|
||||||
"foreignKeys": {
|
|
||||||
"users_to_sandboxes_userId_user_id_fk": {
|
|
||||||
"name": "users_to_sandboxes_userId_user_id_fk",
|
|
||||||
"tableFrom": "users_to_sandboxes",
|
|
||||||
"tableTo": "user",
|
|
||||||
"columnsFrom": [
|
|
||||||
"userId"
|
|
||||||
],
|
|
||||||
"columnsTo": [
|
|
||||||
"id"
|
|
||||||
],
|
|
||||||
"onDelete": "no action",
|
|
||||||
"onUpdate": "no action"
|
|
||||||
},
|
|
||||||
"users_to_sandboxes_sandboxId_sandbox_id_fk": {
|
|
||||||
"name": "users_to_sandboxes_sandboxId_sandbox_id_fk",
|
|
||||||
"tableFrom": "users_to_sandboxes",
|
|
||||||
"tableTo": "sandbox",
|
|
||||||
"columnsFrom": [
|
|
||||||
"sandboxId"
|
|
||||||
],
|
|
||||||
"columnsTo": [
|
|
||||||
"id"
|
|
||||||
],
|
|
||||||
"onDelete": "no action",
|
|
||||||
"onUpdate": "no action"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"compositePrimaryKeys": {},
|
|
||||||
"uniqueConstraints": {}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"enums": {},
|
|
||||||
"_meta": {
|
|
||||||
"schemas": {},
|
|
||||||
"tables": {},
|
|
||||||
"columns": {}
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,55 +1,13 @@
|
|||||||
{
|
{
|
||||||
"version": "5",
|
"version": "5",
|
||||||
"dialect": "sqlite",
|
"dialect": "sqlite",
|
||||||
"entries": [
|
"entries": [
|
||||||
{
|
{
|
||||||
"idx": 0,
|
"idx": 0,
|
||||||
"version": "5",
|
"version": "5",
|
||||||
"when": 1714540200800,
|
"when": 1718032216030,
|
||||||
"tag": "0000_big_rogue",
|
"tag": "0000_melodic_the_captain",
|
||||||
"breakpoints": true
|
"breakpoints": true
|
||||||
},
|
}
|
||||||
{
|
]
|
||||||
"idx": 1,
|
}
|
||||||
"version": "5",
|
|
||||||
"when": 1714541190588,
|
|
||||||
"tag": "0001_empty_black_knight",
|
|
||||||
"breakpoints": true
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"idx": 2,
|
|
||||||
"version": "5",
|
|
||||||
"when": 1714541209173,
|
|
||||||
"tag": "0002_sour_ego",
|
|
||||||
"breakpoints": true
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"idx": 3,
|
|
||||||
"version": "5",
|
|
||||||
"when": 1714541233589,
|
|
||||||
"tag": "0003_pale_overlord",
|
|
||||||
"breakpoints": true
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"idx": 4,
|
|
||||||
"version": "5",
|
|
||||||
"when": 1714565073180,
|
|
||||||
"tag": "0004_cuddly_wolf_cub",
|
|
||||||
"breakpoints": true
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"idx": 5,
|
|
||||||
"version": "5",
|
|
||||||
"when": 1714950365718,
|
|
||||||
"tag": "0005_last_the_twelve",
|
|
||||||
"breakpoints": true
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"idx": 6,
|
|
||||||
"version": "5",
|
|
||||||
"when": 1716432225404,
|
|
||||||
"tag": "0006_lively_mattie_franklin",
|
|
||||||
"breakpoints": true
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
@ -31,7 +31,7 @@ export const sandbox = sqliteTable("sandbox", {
|
|||||||
createdAt: integer("createdAt", { mode: "timestamp_ms" }),
|
createdAt: integer("createdAt", { mode: "timestamp_ms" }),
|
||||||
userId: text("user_id")
|
userId: text("user_id")
|
||||||
.notNull()
|
.notNull()
|
||||||
.references(() => user.id),
|
.references(() => user.id, { onDelete: "cascade" }),
|
||||||
});
|
});
|
||||||
|
|
||||||
export type Sandbox = typeof sandbox.$inferSelect;
|
export type Sandbox = typeof sandbox.$inferSelect;
|
||||||
|
153
backend/server/package-lock.json
generated
153
backend/server/package-lock.json
generated
@ -9,7 +9,6 @@
|
|||||||
"version": "1.0.0",
|
"version": "1.0.0",
|
||||||
"license": "ISC",
|
"license": "ISC",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@e2b/code-interpreter": "^0.0.7",
|
|
||||||
"concurrently": "^8.2.2",
|
"concurrently": "^8.2.2",
|
||||||
"cors": "^2.8.5",
|
"cors": "^2.8.5",
|
||||||
"dotenv": "^16.4.5",
|
"dotenv": "^16.4.5",
|
||||||
@ -51,39 +50,6 @@
|
|||||||
"node": ">=12"
|
"node": ">=12"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@e2b/code-interpreter": {
|
|
||||||
"version": "0.0.7",
|
|
||||||
"resolved": "https://registry.npmjs.org/@e2b/code-interpreter/-/code-interpreter-0.0.7.tgz",
|
|
||||||
"integrity": "sha512-e8nAY4zXU2b9nKthqq/pCPlTVD7f01dtzCtvabWmhlx7Wq+AUln14Q1Wf+uRVJXHkwS9BDv2CupdZpUChsjoCA==",
|
|
||||||
"dependencies": {
|
|
||||||
"e2b": "^0.16.1",
|
|
||||||
"isomorphic-ws": "^5.0.0",
|
|
||||||
"ws": "^8.15.1"
|
|
||||||
},
|
|
||||||
"engines": {
|
|
||||||
"node": ">=18"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/@e2b/code-interpreter/node_modules/ws": {
|
|
||||||
"version": "8.17.0",
|
|
||||||
"resolved": "https://registry.npmjs.org/ws/-/ws-8.17.0.tgz",
|
|
||||||
"integrity": "sha512-uJq6108EgZMAl20KagGkzCKfMEjxmKvZHG7Tlq0Z6nOky7YF7aq4mOx6xK8TJ/i1LeK4Qus7INktacctDgY8Ow==",
|
|
||||||
"engines": {
|
|
||||||
"node": ">=10.0.0"
|
|
||||||
},
|
|
||||||
"peerDependencies": {
|
|
||||||
"bufferutil": "^4.0.1",
|
|
||||||
"utf-8-validate": ">=5.0.2"
|
|
||||||
},
|
|
||||||
"peerDependenciesMeta": {
|
|
||||||
"bufferutil": {
|
|
||||||
"optional": true
|
|
||||||
},
|
|
||||||
"utf-8-validate": {
|
|
||||||
"optional": true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/@jridgewell/resolve-uri": {
|
"node_modules/@jridgewell/resolve-uri": {
|
||||||
"version": "3.1.2",
|
"version": "3.1.2",
|
||||||
"resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz",
|
"resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz",
|
||||||
@ -403,19 +369,6 @@
|
|||||||
"node": ">=8"
|
"node": ">=8"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/bufferutil": {
|
|
||||||
"version": "4.0.8",
|
|
||||||
"resolved": "https://registry.npmjs.org/bufferutil/-/bufferutil-4.0.8.tgz",
|
|
||||||
"integrity": "sha512-4T53u4PdgsXqKaIctwF8ifXlRTTmEPJ8iEPWFdGZvcf7sbwYo6FKFEX9eNNAnzFZ7EzJAQ3CJeOtCRA4rDp7Pw==",
|
|
||||||
"hasInstallScript": true,
|
|
||||||
"optional": true,
|
|
||||||
"dependencies": {
|
|
||||||
"node-gyp-build": "^4.3.0"
|
|
||||||
},
|
|
||||||
"engines": {
|
|
||||||
"node": ">=6.14.2"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/bytes": {
|
"node_modules/bytes": {
|
||||||
"version": "3.1.2",
|
"version": "3.1.2",
|
||||||
"resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz",
|
"resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz",
|
||||||
@ -709,59 +662,6 @@
|
|||||||
"url": "https://dotenvx.com"
|
"url": "https://dotenvx.com"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/e2b": {
|
|
||||||
"version": "0.16.1",
|
|
||||||
"resolved": "https://registry.npmjs.org/e2b/-/e2b-0.16.1.tgz",
|
|
||||||
"integrity": "sha512-2L1R/REEB+EezD4Q4MmcXXNATjvCYov2lv/69+PY6V95+wl1PZblIMTYAe7USxX6P6sqANxNs+kXqZr6RvXkSw==",
|
|
||||||
"dependencies": {
|
|
||||||
"isomorphic-ws": "^5.0.0",
|
|
||||||
"normalize-path": "^3.0.0",
|
|
||||||
"openapi-typescript-fetch": "^1.1.3",
|
|
||||||
"path-browserify": "^1.0.1",
|
|
||||||
"platform": "^1.3.6",
|
|
||||||
"ws": "^8.15.1"
|
|
||||||
},
|
|
||||||
"engines": {
|
|
||||||
"node": ">=18"
|
|
||||||
},
|
|
||||||
"optionalDependencies": {
|
|
||||||
"bufferutil": "^4.0.8",
|
|
||||||
"utf-8-validate": "^6.0.3"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/e2b/node_modules/utf-8-validate": {
|
|
||||||
"version": "6.0.4",
|
|
||||||
"resolved": "https://registry.npmjs.org/utf-8-validate/-/utf-8-validate-6.0.4.tgz",
|
|
||||||
"integrity": "sha512-xu9GQDeFp+eZ6LnCywXN/zBancWvOpUMzgjLPSjy4BRHSmTelvn2E0DG0o1sTiw5hkCKBHo8rwSKncfRfv2EEQ==",
|
|
||||||
"hasInstallScript": true,
|
|
||||||
"optional": true,
|
|
||||||
"dependencies": {
|
|
||||||
"node-gyp-build": "^4.3.0"
|
|
||||||
},
|
|
||||||
"engines": {
|
|
||||||
"node": ">=6.14.2"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/e2b/node_modules/ws": {
|
|
||||||
"version": "8.17.0",
|
|
||||||
"resolved": "https://registry.npmjs.org/ws/-/ws-8.17.0.tgz",
|
|
||||||
"integrity": "sha512-uJq6108EgZMAl20KagGkzCKfMEjxmKvZHG7Tlq0Z6nOky7YF7aq4mOx6xK8TJ/i1LeK4Qus7INktacctDgY8Ow==",
|
|
||||||
"engines": {
|
|
||||||
"node": ">=10.0.0"
|
|
||||||
},
|
|
||||||
"peerDependencies": {
|
|
||||||
"bufferutil": "^4.0.1",
|
|
||||||
"utf-8-validate": ">=5.0.2"
|
|
||||||
},
|
|
||||||
"peerDependenciesMeta": {
|
|
||||||
"bufferutil": {
|
|
||||||
"optional": true
|
|
||||||
},
|
|
||||||
"utf-8-validate": {
|
|
||||||
"optional": true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/ee-first": {
|
"node_modules/ee-first": {
|
||||||
"version": "1.1.1",
|
"version": "1.1.1",
|
||||||
"resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz",
|
"resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz",
|
||||||
@ -1182,14 +1082,6 @@
|
|||||||
"node": ">=0.12.0"
|
"node": ">=0.12.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/isomorphic-ws": {
|
|
||||||
"version": "5.0.0",
|
|
||||||
"resolved": "https://registry.npmjs.org/isomorphic-ws/-/isomorphic-ws-5.0.0.tgz",
|
|
||||||
"integrity": "sha512-muId7Zzn9ywDsyXgTIafTry2sV3nySZeUDe6YedVd1Hvuuep5AsIlqK+XefWpYTyJG5e503F2xIuT2lcU6rCSw==",
|
|
||||||
"peerDependencies": {
|
|
||||||
"ws": "*"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/lodash": {
|
"node_modules/lodash": {
|
||||||
"version": "4.17.21",
|
"version": "4.17.21",
|
||||||
"resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz",
|
"resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz",
|
||||||
@ -1294,17 +1186,6 @@
|
|||||||
"node": ">= 0.6"
|
"node": ">= 0.6"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/node-gyp-build": {
|
|
||||||
"version": "4.8.1",
|
|
||||||
"resolved": "https://registry.npmjs.org/node-gyp-build/-/node-gyp-build-4.8.1.tgz",
|
|
||||||
"integrity": "sha512-OSs33Z9yWr148JZcbZd5WiAXhh/n9z8TxQcdMhIOlpN9AhWpLfvVFO73+m77bBABQMaY9XSvIa+qk0jlI7Gcaw==",
|
|
||||||
"optional": true,
|
|
||||||
"bin": {
|
|
||||||
"node-gyp-build": "bin.js",
|
|
||||||
"node-gyp-build-optional": "optional.js",
|
|
||||||
"node-gyp-build-test": "build-test.js"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/node-pty": {
|
"node_modules/node-pty": {
|
||||||
"version": "1.0.0",
|
"version": "1.0.0",
|
||||||
"resolved": "https://registry.npmjs.org/node-pty/-/node-pty-1.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/node-pty/-/node-pty-1.0.0.tgz",
|
||||||
@ -1384,6 +1265,7 @@
|
|||||||
"version": "3.0.0",
|
"version": "3.0.0",
|
||||||
"resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz",
|
||||||
"integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==",
|
"integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==",
|
||||||
|
"dev": true,
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">=0.10.0"
|
"node": ">=0.10.0"
|
||||||
}
|
}
|
||||||
@ -1415,15 +1297,6 @@
|
|||||||
"node": ">= 0.8"
|
"node": ">= 0.8"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/openapi-typescript-fetch": {
|
|
||||||
"version": "1.1.3",
|
|
||||||
"resolved": "https://registry.npmjs.org/openapi-typescript-fetch/-/openapi-typescript-fetch-1.1.3.tgz",
|
|
||||||
"integrity": "sha512-smLZPck4OkKMNExcw8jMgrMOGgVGx2N/s6DbKL2ftNl77g5HfoGpZGFy79RBzU/EkaO0OZpwBnslfdBfh7ZcWg==",
|
|
||||||
"engines": {
|
|
||||||
"node": ">= 12.0.0",
|
|
||||||
"npm": ">= 7.0.0"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/parseurl": {
|
"node_modules/parseurl": {
|
||||||
"version": "1.3.3",
|
"version": "1.3.3",
|
||||||
"resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz",
|
"resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz",
|
||||||
@ -1432,11 +1305,6 @@
|
|||||||
"node": ">= 0.8"
|
"node": ">= 0.8"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/path-browserify": {
|
|
||||||
"version": "1.0.1",
|
|
||||||
"resolved": "https://registry.npmjs.org/path-browserify/-/path-browserify-1.0.1.tgz",
|
|
||||||
"integrity": "sha512-b7uo2UCUOYZcnF/3ID0lulOJi/bafxa1xPe7ZPsammBSpjSWQkjNxlt635YGS2MiR9GjvuXCtz2emr3jbsz98g=="
|
|
||||||
},
|
|
||||||
"node_modules/path-to-regexp": {
|
"node_modules/path-to-regexp": {
|
||||||
"version": "0.1.7",
|
"version": "0.1.7",
|
||||||
"resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.7.tgz",
|
"resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.7.tgz",
|
||||||
@ -1454,11 +1322,6 @@
|
|||||||
"url": "https://github.com/sponsors/jonschlinkert"
|
"url": "https://github.com/sponsors/jonschlinkert"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/platform": {
|
|
||||||
"version": "1.3.6",
|
|
||||||
"resolved": "https://registry.npmjs.org/platform/-/platform-1.3.6.tgz",
|
|
||||||
"integrity": "sha512-fnWVljUchTro6RiCFvCXBbNhJc2NijN7oIQxbwsyL0buWJPG85v81ehlHI9fXrJsMNgTofEoWIQeClKpgxFLrg=="
|
|
||||||
},
|
|
||||||
"node_modules/proxy-addr": {
|
"node_modules/proxy-addr": {
|
||||||
"version": "2.0.7",
|
"version": "2.0.7",
|
||||||
"resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.7.tgz",
|
"resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.7.tgz",
|
||||||
@ -1972,20 +1835,6 @@
|
|||||||
"node": ">= 0.8"
|
"node": ">= 0.8"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/utf-8-validate": {
|
|
||||||
"version": "5.0.10",
|
|
||||||
"resolved": "https://registry.npmjs.org/utf-8-validate/-/utf-8-validate-5.0.10.tgz",
|
|
||||||
"integrity": "sha512-Z6czzLq4u8fPOyx7TU6X3dvUZVvoJmxSQ+IcrlmagKhilxlhZgxPK6C5Jqbkw1IDUmFTM+cz9QDnnLTwDz/2gQ==",
|
|
||||||
"hasInstallScript": true,
|
|
||||||
"optional": true,
|
|
||||||
"peer": true,
|
|
||||||
"dependencies": {
|
|
||||||
"node-gyp-build": "^4.3.0"
|
|
||||||
},
|
|
||||||
"engines": {
|
|
||||||
"node": ">=6.14.2"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/utils-merge": {
|
"node_modules/utils-merge": {
|
||||||
"version": "1.0.1",
|
"version": "1.0.1",
|
||||||
"resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz",
|
"resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz",
|
||||||
|
@ -11,7 +11,6 @@
|
|||||||
"author": "",
|
"author": "",
|
||||||
"license": "ISC",
|
"license": "ISC",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@e2b/code-interpreter": "^0.0.7",
|
|
||||||
"concurrently": "^8.2.2",
|
"concurrently": "^8.2.2",
|
||||||
"cors": "^2.8.5",
|
"cors": "^2.8.5",
|
||||||
"dotenv": "^16.4.5",
|
"dotenv": "^16.4.5",
|
||||||
|
@ -18,7 +18,7 @@ import {
|
|||||||
renameFile,
|
renameFile,
|
||||||
saveFile,
|
saveFile,
|
||||||
} from "./utils";
|
} from "./utils";
|
||||||
import { Sandbox, Process, ProcessMessage } from "e2b";
|
import { IDisposable, IPty, spawn } from "node-pty";
|
||||||
import {
|
import {
|
||||||
MAX_BODY_SIZE,
|
MAX_BODY_SIZE,
|
||||||
createFileRL,
|
createFileRL,
|
||||||
@ -44,10 +44,7 @@ let inactivityTimeout: NodeJS.Timeout | null = null;
|
|||||||
let isOwnerConnected = false;
|
let isOwnerConnected = false;
|
||||||
|
|
||||||
const terminals: {
|
const terminals: {
|
||||||
[id: string]: Process;
|
[id: string]: { terminal: IPty; onData: IDisposable; onExit: IDisposable };
|
||||||
} = {};
|
|
||||||
const containers: {
|
|
||||||
[id: string]: Sandbox;
|
|
||||||
} = {};
|
} = {};
|
||||||
|
|
||||||
const dirName = path.join(__dirname, "..");
|
const dirName = path.join(__dirname, "..");
|
||||||
@ -103,32 +100,6 @@ io.use(async (socket, next) => {
|
|||||||
next();
|
next();
|
||||||
});
|
});
|
||||||
|
|
||||||
class LockManager {
|
|
||||||
private locks: { [key: string]: Promise<any> };
|
|
||||||
|
|
||||||
constructor() {
|
|
||||||
this.locks = {};
|
|
||||||
}
|
|
||||||
|
|
||||||
async acquireLock<T>(key: string, task: () => Promise<T>): Promise<T> {
|
|
||||||
if (!this.locks[key]) {
|
|
||||||
this.locks[key] = new Promise<T>(async (resolve, reject) => {
|
|
||||||
try {
|
|
||||||
const result = await task();
|
|
||||||
resolve(result);
|
|
||||||
} catch (error) {
|
|
||||||
reject(error);
|
|
||||||
} finally {
|
|
||||||
delete this.locks[key];
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
return await this.locks[key];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
const lockManager = new LockManager();
|
|
||||||
|
|
||||||
io.on("connection", async (socket) => {
|
io.on("connection", async (socket) => {
|
||||||
if (inactivityTimeout) clearTimeout(inactivityTimeout);
|
if (inactivityTimeout) clearTimeout(inactivityTimeout);
|
||||||
|
|
||||||
@ -147,16 +118,6 @@ io.on("connection", async (socket) => {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
await lockManager.acquireLock(data.sandboxId, async () => {
|
|
||||||
if (!containers[data.sandboxId]) {
|
|
||||||
console.log("Creating container ", data.sandboxId);
|
|
||||||
containers[data.sandboxId] = await Sandbox.create({
|
|
||||||
template: "terminal",
|
|
||||||
});
|
|
||||||
console.log("Created.");
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
const sandboxFiles = await getSandboxFiles(data.sandboxId);
|
const sandboxFiles = await getSandboxFiles(data.sandboxId);
|
||||||
sandboxFiles.fileData.forEach((file) => {
|
sandboxFiles.fileData.forEach((file) => {
|
||||||
const filePath = path.join(dirName, file.id);
|
const filePath = path.join(dirName, file.id);
|
||||||
@ -358,56 +319,42 @@ io.on("connection", async (socket) => {
|
|||||||
callback(newFiles.files);
|
callback(newFiles.files);
|
||||||
});
|
});
|
||||||
|
|
||||||
function toBackslashNotation(input: string) {
|
socket.on("createTerminal", (id: string, callback) => {
|
||||||
return input
|
|
||||||
.replace(/\\/g, "\\\\") // Escape backslashes
|
|
||||||
.replace(/\n/g, "\\n") // Escape newlines
|
|
||||||
.replace(/\r/g, "\\r") // Escape carriage returns
|
|
||||||
.replace(/\t/g, "\\t") // Escape tabs
|
|
||||||
.replace(/"/g, '\\"') // Escape double quotes
|
|
||||||
.replace(/'/g, "\\'") // Escape single quotes
|
|
||||||
.replace(/\f/g, "\\f") // Escape form feeds
|
|
||||||
.replace(/\b/g, "\\b") // Escape backspaces
|
|
||||||
.replace(/\v/g, "\\v") // Escape vertical tabs
|
|
||||||
.replace(/\0/g, "\\0") // Escape null characters
|
|
||||||
.replace(/\a/g, "\\a") // Escape alert (bell)
|
|
||||||
.replace(/\e/g, "\\e"); // Escape escape
|
|
||||||
}
|
|
||||||
|
|
||||||
socket.on("createTerminal", async (id: string, callback) => {
|
|
||||||
if (terminals[id] || Object.keys(terminals).length >= 4) {
|
if (terminals[id] || Object.keys(terminals).length >= 4) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const onData = (data: ProcessMessage) => {
|
const pty = spawn(os.platform() === "win32" ? "cmd.exe" : "bash", [], {
|
||||||
console.log("process", toBackslashNotation(data.toString()));
|
name: "xterm",
|
||||||
|
cols: 100,
|
||||||
|
cwd: path.join(dirName, "projects", data.sandboxId),
|
||||||
|
});
|
||||||
|
|
||||||
|
const onData = pty.onData((data) => {
|
||||||
io.emit("terminalResponse", {
|
io.emit("terminalResponse", {
|
||||||
id,
|
id,
|
||||||
data: data.toString() + "\r\n",
|
data,
|
||||||
});
|
});
|
||||||
};
|
|
||||||
|
|
||||||
await lockManager.acquireLock(data.sandboxId, async () => {
|
|
||||||
console.log("Creating terminal", id);
|
|
||||||
terminals[id] = await containers[data.sandboxId].process.start({
|
|
||||||
cmd: 'TERM=xterm script -c "screen" /dev/null', // xterm vt100
|
|
||||||
onStdout: onData,
|
|
||||||
onStderr: onData,
|
|
||||||
onExit: (code) => console.log("exit :(", code),
|
|
||||||
});
|
|
||||||
await terminals[id].sendStdin("clear\r\n");
|
|
||||||
await terminals[id].sendStdin("export PS1='user> '\r\n");
|
|
||||||
await terminals[id].sendStdin("clear\r\n");
|
|
||||||
console.log("Created terminal", id);
|
|
||||||
});
|
});
|
||||||
|
|
||||||
|
const onExit = pty.onExit((code) => console.log("exit :(", code));
|
||||||
|
|
||||||
|
pty.write("export PS1='\\u > '\r");
|
||||||
|
pty.write("clear\r");
|
||||||
|
|
||||||
|
terminals[id] = {
|
||||||
|
terminal: pty,
|
||||||
|
onData,
|
||||||
|
onExit,
|
||||||
|
};
|
||||||
|
|
||||||
callback();
|
callback();
|
||||||
});
|
});
|
||||||
|
|
||||||
socket.on("resizeTerminal", (dimensions: { cols: number; rows: number }) => {
|
socket.on("resizeTerminal", (dimensions: { cols: number; rows: number }) => {
|
||||||
/*Object.values(terminals).forEach((t) => {
|
Object.values(terminals).forEach((t) => {
|
||||||
t.terminal.resize(dimensions.cols, dimensions.rows);
|
t.terminal.resize(dimensions.cols, dimensions.rows);
|
||||||
});*/
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
socket.on("terminalData", (id: string, data: string) => {
|
socket.on("terminalData", (id: string, data: string) => {
|
||||||
@ -416,19 +363,19 @@ io.on("connection", async (socket) => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
console.log(`Writing ${toBackslashNotation(data)} to ${id}`);
|
terminals[id].terminal.write(data);
|
||||||
terminals[id].sendStdin(data);
|
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
console.log("Error writing to terminal", e);
|
console.log("Error writing to terminal", e);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
socket.on("closeTerminal", async (id: string, callback) => {
|
socket.on("closeTerminal", (id: string, callback) => {
|
||||||
if (!terminals[id]) {
|
if (!terminals[id]) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
await terminals[id].kill();
|
terminals[id].onData.dispose();
|
||||||
|
terminals[id].onExit.dispose();
|
||||||
delete terminals[id];
|
delete terminals[id];
|
||||||
|
|
||||||
callback();
|
callback();
|
||||||
@ -482,20 +429,12 @@ io.on("connection", async (socket) => {
|
|||||||
socket.on("disconnect", async () => {
|
socket.on("disconnect", async () => {
|
||||||
if (data.isOwner) {
|
if (data.isOwner) {
|
||||||
Object.entries(terminals).forEach((t) => {
|
Object.entries(terminals).forEach((t) => {
|
||||||
const terminal = t[1];
|
const { terminal, onData, onExit } = t[1];
|
||||||
terminal.kill();
|
onData.dispose();
|
||||||
|
onExit.dispose();
|
||||||
delete terminals[t[0]];
|
delete terminals[t[0]];
|
||||||
});
|
});
|
||||||
|
|
||||||
await lockManager.acquireLock(data.sandboxId, async () => {
|
|
||||||
if (containers[data.sandboxId]) {
|
|
||||||
console.log("Closing container", data.sandboxId);
|
|
||||||
await containers[data.sandboxId].close();
|
|
||||||
delete containers[data.sandboxId];
|
|
||||||
console.log("Closed");
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
socket.broadcast.emit(
|
socket.broadcast.emit(
|
||||||
"disableAccess",
|
"disableAccess",
|
||||||
"The sandbox owner has disconnected."
|
"The sandbox owner has disconnected."
|
||||||
|
@ -1,9 +1,9 @@
|
|||||||
"use client"
|
"use client"
|
||||||
|
|
||||||
import { useEffect, useRef, useState } from "react"
|
import { SetStateAction, useCallback, useEffect, useRef, useState } from "react"
|
||||||
import monaco from "monaco-editor"
|
import monaco from "monaco-editor"
|
||||||
import Editor, { BeforeMount, OnMount } from "@monaco-editor/react"
|
import Editor, { BeforeMount, OnMount } from "@monaco-editor/react"
|
||||||
import { io } from "socket.io-client"
|
import { Socket, io } from "socket.io-client"
|
||||||
import { toast } from "sonner"
|
import { toast } from "sonner"
|
||||||
import { useClerk } from "@clerk/nextjs"
|
import { useClerk } from "@clerk/nextjs"
|
||||||
|
|
||||||
@ -23,7 +23,7 @@ import Tab from "../ui/tab"
|
|||||||
import Sidebar from "./sidebar"
|
import Sidebar from "./sidebar"
|
||||||
import GenerateInput from "./generate"
|
import GenerateInput from "./generate"
|
||||||
import { Sandbox, User, TFile, TFolder, TTab } from "@/lib/types"
|
import { Sandbox, User, TFile, TFolder, TTab } from "@/lib/types"
|
||||||
import { addNew, processFileType, validateName } from "@/lib/utils"
|
import { addNew, processFileType, validateName, debounce } from "@/lib/utils"
|
||||||
import { Cursors } from "./live/cursors"
|
import { Cursors } from "./live/cursors"
|
||||||
import { Terminal } from "@xterm/xterm"
|
import { Terminal } from "@xterm/xterm"
|
||||||
import DisableAccessModal from "./live/disableModal"
|
import DisableAccessModal from "./live/disableModal"
|
||||||
@ -41,12 +41,16 @@ export default function CodeEditor({
|
|||||||
sandboxData: Sandbox
|
sandboxData: Sandbox
|
||||||
reactDefinitionFile: string
|
reactDefinitionFile: string
|
||||||
}) {
|
}) {
|
||||||
const socket = io(
|
const socketRef = useRef<Socket | null>(null);
|
||||||
`http://localhost:${process.env.NEXT_PUBLIC_SERVER_PORT}?userId=${userData.id}&sandboxId=${sandboxData.id}`,
|
|
||||||
{
|
// Initialize socket connection if it doesn't exist
|
||||||
timeout: 2000,
|
if (!socketRef.current) {
|
||||||
}
|
socketRef.current = io(
|
||||||
)
|
`http://localhost:${process.env.NEXT_PUBLIC_SERVER_PORT}?userId=${userData.id}&sandboxId=${sandboxData.id}`,
|
||||||
|
{
|
||||||
|
timeout: 2000,
|
||||||
|
}
|
||||||
|
);}
|
||||||
|
|
||||||
const [isPreviewCollapsed, setIsPreviewCollapsed] = useState(true)
|
const [isPreviewCollapsed, setIsPreviewCollapsed] = useState(true)
|
||||||
const [disableAccess, setDisableAccess] = useState({
|
const [disableAccess, setDisableAccess] = useState({
|
||||||
@ -290,26 +294,33 @@ export default function CodeEditor({
|
|||||||
}, [decorations.options])
|
}, [decorations.options])
|
||||||
|
|
||||||
// Save file keybinding logic effect
|
// Save file keybinding logic effect
|
||||||
|
const debouncedSaveData = useCallback(
|
||||||
|
debounce((value: string | undefined, activeFileId: string | undefined) => {
|
||||||
|
setTabs((prev) =>
|
||||||
|
prev.map((tab) =>
|
||||||
|
tab.id === activeFileId ? { ...tab, saved: true } : tab
|
||||||
|
)
|
||||||
|
);
|
||||||
|
console.log(`Saving file...${activeFileId}`);
|
||||||
|
console.log(`Saving file...${value}`);
|
||||||
|
socketRef.current?.emit("saveFile", activeFileId, value);
|
||||||
|
}, Number(process.env.FILE_SAVE_DEBOUNCE_DELAY)||1000),
|
||||||
|
[socketRef]
|
||||||
|
);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
const down = (e: KeyboardEvent) => {
|
const down = (e: KeyboardEvent) => {
|
||||||
if (e.key === "s" && (e.metaKey || e.ctrlKey)) {
|
if (e.key === "s" && (e.metaKey || e.ctrlKey)) {
|
||||||
e.preventDefault()
|
e.preventDefault();
|
||||||
|
debouncedSaveData(editorRef?.getValue(), activeFileId);
|
||||||
setTabs((prev) =>
|
|
||||||
prev.map((tab) =>
|
|
||||||
tab.id === activeFileId ? { ...tab, saved: true } : tab
|
|
||||||
)
|
|
||||||
)
|
|
||||||
|
|
||||||
socket.emit("saveFile", activeFileId, editorRef?.getValue())
|
|
||||||
}
|
}
|
||||||
}
|
};
|
||||||
document.addEventListener("keydown", down)
|
document.addEventListener("keydown", down);
|
||||||
|
|
||||||
return () => {
|
return () => {
|
||||||
document.removeEventListener("keydown", down)
|
document.removeEventListener("keydown", down);
|
||||||
}
|
};
|
||||||
}, [tabs, activeFileId])
|
}, [activeFileId, tabs, debouncedSaveData]);
|
||||||
|
|
||||||
// Liveblocks live collaboration setup effect
|
// Liveblocks live collaboration setup effect
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
@ -358,10 +369,10 @@ export default function CodeEditor({
|
|||||||
|
|
||||||
// Connection/disconnection effect
|
// Connection/disconnection effect
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
socket.connect()
|
socketRef.current?.connect()
|
||||||
|
|
||||||
return () => {
|
return () => {
|
||||||
socket.disconnect()
|
socketRef.current?.disconnect()
|
||||||
}
|
}
|
||||||
}, [])
|
}, [])
|
||||||
|
|
||||||
@ -396,20 +407,20 @@ export default function CodeEditor({
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
socket.on("connect", onConnect)
|
socketRef.current?.on("connect", onConnect)
|
||||||
socket.on("disconnect", onDisconnect)
|
socketRef.current?.on("disconnect", onDisconnect)
|
||||||
socket.on("loaded", onLoadedEvent)
|
socketRef.current?.on("loaded", onLoadedEvent)
|
||||||
socket.on("rateLimit", onRateLimit)
|
socketRef.current?.on("rateLimit", onRateLimit)
|
||||||
socket.on("terminalResponse", onTerminalResponse)
|
socketRef.current?.on("terminalResponse", onTerminalResponse)
|
||||||
socket.on("disableAccess", onDisableAccess)
|
socketRef.current?.on("disableAccess", onDisableAccess)
|
||||||
|
|
||||||
return () => {
|
return () => {
|
||||||
socket.off("connect", onConnect)
|
socketRef.current?.off("connect", onConnect)
|
||||||
socket.off("disconnect", onDisconnect)
|
socketRef.current?.off("disconnect", onDisconnect)
|
||||||
socket.off("loaded", onLoadedEvent)
|
socketRef.current?.off("loaded", onLoadedEvent)
|
||||||
socket.off("rateLimit", onRateLimit)
|
socketRef.current?.off("rateLimit", onRateLimit)
|
||||||
socket.off("terminalResponse", onTerminalResponse)
|
socketRef.current?.off("terminalResponse", onTerminalResponse)
|
||||||
socket.off("disableAccess", onDisableAccess)
|
socketRef.current?.off("disableAccess", onDisableAccess)
|
||||||
}
|
}
|
||||||
// }, []);
|
// }, []);
|
||||||
}, [terminals])
|
}, [terminals])
|
||||||
@ -417,31 +428,43 @@ export default function CodeEditor({
|
|||||||
// Helper functions for tabs:
|
// Helper functions for tabs:
|
||||||
|
|
||||||
// Select file and load content
|
// Select file and load content
|
||||||
const selectFile = (tab: TTab) => {
|
|
||||||
if (tab.id === activeFileId) return
|
|
||||||
|
|
||||||
setGenerate((prev) => {
|
// Initialize debounced function once
|
||||||
return {
|
const fileCache = useRef(new Map());
|
||||||
...prev,
|
|
||||||
show: false,
|
|
||||||
}
|
|
||||||
})
|
|
||||||
const exists = tabs.find((t) => t.id === tab.id)
|
|
||||||
|
|
||||||
|
// Debounced function to get file content
|
||||||
|
const debouncedGetFile = useCallback(
|
||||||
|
debounce((tabId, callback) => {
|
||||||
|
socketRef.current?.emit('getFile', tabId, callback);
|
||||||
|
}, 300), // 300ms debounce delay, adjust as needed
|
||||||
|
[]
|
||||||
|
);
|
||||||
|
|
||||||
|
const selectFile = useCallback((tab: TTab) => {
|
||||||
|
if (tab.id === activeFileId) return;
|
||||||
|
|
||||||
|
setGenerate((prev) => ({ ...prev, show: false }));
|
||||||
|
|
||||||
|
const exists = tabs.find((t) => t.id === tab.id);
|
||||||
setTabs((prev) => {
|
setTabs((prev) => {
|
||||||
if (exists) {
|
if (exists) {
|
||||||
setActiveFileId(exists.id)
|
setActiveFileId(exists.id);
|
||||||
return prev
|
return prev;
|
||||||
}
|
}
|
||||||
return [...prev, tab]
|
return [...prev, tab];
|
||||||
})
|
});
|
||||||
|
|
||||||
socket.emit("getFile", tab.id, (response: string) => {
|
if (fileCache.current.has(tab.id)) {
|
||||||
setActiveFileContent(response)
|
setActiveFileContent(fileCache.current.get(tab.id));
|
||||||
})
|
} else {
|
||||||
setEditorLanguage(processFileType(tab.name))
|
debouncedGetFile(tab.id, (response: SetStateAction<string>) => {
|
||||||
setActiveFileId(tab.id)
|
fileCache.current.set(tab.id, response);
|
||||||
}
|
setActiveFileContent(response);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
setEditorLanguage(processFileType(tab.name));
|
||||||
|
setActiveFileId(tab.id);
|
||||||
|
}, [activeFileId, tabs, debouncedGetFile]);
|
||||||
|
|
||||||
// Close tab and remove from tabs
|
// Close tab and remove from tabs
|
||||||
const closeTab = (id: string) => {
|
const closeTab = (id: string) => {
|
||||||
@ -515,7 +538,7 @@ export default function CodeEditor({
|
|||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
socket.emit("renameFile", id, newName)
|
socketRef.current?.emit("renameFile", id, newName)
|
||||||
setTabs((prev) =>
|
setTabs((prev) =>
|
||||||
prev.map((tab) => (tab.id === id ? { ...tab, name: newName } : tab))
|
prev.map((tab) => (tab.id === id ? { ...tab, name: newName } : tab))
|
||||||
)
|
)
|
||||||
@ -524,7 +547,7 @@ export default function CodeEditor({
|
|||||||
}
|
}
|
||||||
|
|
||||||
const handleDeleteFile = (file: TFile) => {
|
const handleDeleteFile = (file: TFile) => {
|
||||||
socket.emit("deleteFile", file.id, (response: (TFolder | TFile)[]) => {
|
socketRef.current?.emit("deleteFile", file.id, (response: (TFolder | TFile)[]) => {
|
||||||
setFiles(response)
|
setFiles(response)
|
||||||
})
|
})
|
||||||
closeTab(file.id)
|
closeTab(file.id)
|
||||||
@ -534,11 +557,11 @@ export default function CodeEditor({
|
|||||||
setDeletingFolderId(folder.id)
|
setDeletingFolderId(folder.id)
|
||||||
console.log("deleting folder", folder.id)
|
console.log("deleting folder", folder.id)
|
||||||
|
|
||||||
socket.emit("getFolder", folder.id, (response: string[]) =>
|
socketRef.current?.emit("getFolder", folder.id, (response: string[]) =>
|
||||||
closeTabs(response)
|
closeTabs(response)
|
||||||
)
|
)
|
||||||
|
|
||||||
socket.emit("deleteFolder", folder.id, (response: (TFolder | TFile)[]) => {
|
socketRef.current?.emit("deleteFolder", folder.id, (response: (TFolder | TFile)[]) => {
|
||||||
setFiles(response)
|
setFiles(response)
|
||||||
setDeletingFolderId("")
|
setDeletingFolderId("")
|
||||||
})
|
})
|
||||||
@ -565,7 +588,7 @@ export default function CodeEditor({
|
|||||||
{generate.show && ai ? (
|
{generate.show && ai ? (
|
||||||
<GenerateInput
|
<GenerateInput
|
||||||
user={userData}
|
user={userData}
|
||||||
socket={socket}
|
socket={socketRef.current}
|
||||||
width={generate.width - 90}
|
width={generate.width - 90}
|
||||||
data={{
|
data={{
|
||||||
fileName: tabs.find((t) => t.id === activeFileId)?.name ?? "",
|
fileName: tabs.find((t) => t.id === activeFileId)?.name ?? "",
|
||||||
@ -625,7 +648,7 @@ export default function CodeEditor({
|
|||||||
handleRename={handleRename}
|
handleRename={handleRename}
|
||||||
handleDeleteFile={handleDeleteFile}
|
handleDeleteFile={handleDeleteFile}
|
||||||
handleDeleteFolder={handleDeleteFolder}
|
handleDeleteFolder={handleDeleteFolder}
|
||||||
socket={socket}
|
socket={socketRef.current}
|
||||||
setFiles={setFiles}
|
setFiles={setFiles}
|
||||||
addNew={(name, type) => addNew(name, type, setFiles, sandboxData)}
|
addNew={(name, type) => addNew(name, type, setFiles, sandboxData)}
|
||||||
deletingFolderId={deletingFolderId}
|
deletingFolderId={deletingFolderId}
|
||||||
@ -757,7 +780,7 @@ export default function CodeEditor({
|
|||||||
<Terminals
|
<Terminals
|
||||||
terminals={terminals}
|
terminals={terminals}
|
||||||
setTerminals={setTerminals}
|
setTerminals={setTerminals}
|
||||||
socket={socket}
|
socket={socketRef.current}
|
||||||
/>
|
/>
|
||||||
) : (
|
) : (
|
||||||
<div className="w-full h-full flex items-center justify-center text-lg font-medium text-muted-foreground/50 select-none">
|
<div className="w-full h-full flex items-center justify-center text-lg font-medium text-muted-foreground/50 select-none">
|
||||||
@ -772,3 +795,4 @@ export default function CodeEditor({
|
|||||||
</>
|
</>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -61,3 +61,13 @@ export function addNew(
|
|||||||
])
|
])
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function debounce<T extends (...args: any[]) => void>(func: T, wait: number): T {
|
||||||
|
let timeout: NodeJS.Timeout | null = null;
|
||||||
|
return function (...args: Parameters<T>) {
|
||||||
|
if (timeout) {
|
||||||
|
clearTimeout(timeout);
|
||||||
|
}
|
||||||
|
timeout = setTimeout(() => func(...args), wait);
|
||||||
|
} as T;
|
||||||
|
}
|
Reference in New Issue
Block a user