the universal sandbox runtime for agents and humans. pocketenv.io
sandbox openclaw agent claude-code vercel-sandbox deno-sandbox cloudflare-sandbox atproto sprites daytona
7
fork

Configure Feed

Select the types of activity you want to include in your feed.

Add services table and link to sandbox_ports

+1551 -1
+5 -1
apps/api/src/schema/sandbox-ports.ts
··· 7 7 integer, 8 8 } from "drizzle-orm/pg-core"; 9 9 import sandboxes from "./sandboxes"; 10 + import services from "./services"; 10 11 11 12 const sandboxPorts = pgTable( 12 13 "sandbox_ports", 13 14 { 14 - id: text("id").primaryKey().default(sql`xata_id()`), 15 + id: text("id") 16 + .primaryKey() 17 + .default(sql`xata_id()`), 15 18 sandboxId: text("sandbox_id") 16 19 .notNull() 17 20 .references(() => sandboxes.id), 18 21 exposedPort: integer("exposed_port").notNull(), 19 22 previewUrl: text("preview_url"), 20 23 description: text("description"), 24 + serviceId: text("service_id").references(() => services.id), 21 25 createdAt: timestamp("created_at").defaultNow().notNull(), 22 26 updatedAt: timestamp("updated_at").defaultNow().notNull(), 23 27 },
+26
apps/api/src/schema/services.ts
··· 1 + import { type InferInsertModel, type InferSelectModel, sql } from "drizzle-orm"; 2 + import { pgTable, text, timestamp, uniqueIndex } from "drizzle-orm/pg-core"; 3 + import sandboxes from "./sandboxes"; 4 + 5 + const services = pgTable( 6 + "services", 7 + { 8 + id: text("id") 9 + .primaryKey() 10 + .default(sql`xata_id()`), 11 + sandboxId: text("sandbox_id") 12 + .notNull() 13 + .references(() => sandboxes.id), 14 + name: text("name").notNull(), 15 + command: text("command").notNull(), 16 + description: text("description"), 17 + createdAt: timestamp("created_at").defaultNow().notNull(), 18 + updatedAt: timestamp("updated_at").defaultNow().notNull(), 19 + }, 20 + (t) => [uniqueIndex("unique_sandbox_service").on(t.name, t.sandboxId)], 21 + ); 22 + 23 + export type SelectService = InferSelectModel<typeof services>; 24 + export type InsertService = InferInsertModel<typeof services>; 25 + 26 + export default services;
+19
apps/cf-sandbox/drizzle/0032_happy_leech.sql
··· 1 + CREATE OR REPLACE FUNCTION service_id() 2 + RETURNS text AS $$ 3 + SELECT 'svc_' || xata_private.xid(); 4 + $$ LANGUAGE sql IMMUTABLE; 5 + 6 + CREATE TABLE "services" ( 7 + "id" text PRIMARY KEY DEFAULT service_id() NOT NULL, 8 + "sandbox_id" text NOT NULL, 9 + "name" text NOT NULL, 10 + "command" text NOT NULL, 11 + "description" text, 12 + "created_at" timestamp DEFAULT now() NOT NULL, 13 + "updated_at" timestamp DEFAULT now() NOT NULL 14 + ); 15 + --> statement-breakpoint 16 + ALTER TABLE "sandbox_ports" ADD COLUMN "service_id" text;--> statement-breakpoint 17 + ALTER TABLE "services" ADD CONSTRAINT "services_sandbox_id_sandboxes_id_fk" FOREIGN KEY ("sandbox_id") REFERENCES "public"."sandboxes"("id") ON DELETE no action ON UPDATE no action;--> statement-breakpoint 18 + CREATE UNIQUE INDEX "unique_sandbox_service" ON "services" USING btree ("name","sandbox_id");--> statement-breakpoint 19 + ALTER TABLE "sandbox_ports" ADD CONSTRAINT "sandbox_ports_service_id_services_id_fk" FOREIGN KEY ("service_id") REFERENCES "public"."services"("id") ON DELETE no action ON UPDATE no action;
+1438
apps/cf-sandbox/drizzle/meta/0032_snapshot.json
··· 1 + { 2 + "id": "0af35a3f-be0b-4475-8df8-700ef5b39052", 3 + "prevId": "1eb6b42c-adbc-416b-a3c6-577289f7804a", 4 + "version": "7", 5 + "dialect": "postgresql", 6 + "tables": { 7 + "public.authorized_keys": { 8 + "name": "authorized_keys", 9 + "schema": "", 10 + "columns": { 11 + "id": { 12 + "name": "id", 13 + "type": "text", 14 + "primaryKey": true, 15 + "notNull": true, 16 + "default": "xata_id()" 17 + }, 18 + "sandbox_id": { 19 + "name": "sandbox_id", 20 + "type": "text", 21 + "primaryKey": false, 22 + "notNull": false 23 + }, 24 + "public_key": { 25 + "name": "public_key", 26 + "type": "text", 27 + "primaryKey": false, 28 + "notNull": true 29 + }, 30 + "created_at": { 31 + "name": "created_at", 32 + "type": "timestamp", 33 + "primaryKey": false, 34 + "notNull": true, 35 + "default": "now()" 36 + } 37 + }, 38 + "indexes": {}, 39 + "foreignKeys": { 40 + "authorized_keys_sandbox_id_sandboxes_id_fk": { 41 + "name": "authorized_keys_sandbox_id_sandboxes_id_fk", 42 + "tableFrom": "authorized_keys", 43 + "tableTo": "sandboxes", 44 + "columnsFrom": [ 45 + "sandbox_id" 46 + ], 47 + "columnsTo": [ 48 + "id" 49 + ], 50 + "onDelete": "no action", 51 + "onUpdate": "no action" 52 + } 53 + }, 54 + "compositePrimaryKeys": {}, 55 + "uniqueConstraints": {}, 56 + "policies": {}, 57 + "checkConstraints": {}, 58 + "isRLSEnabled": false 59 + }, 60 + "public.files": { 61 + "name": "files", 62 + "schema": "", 63 + "columns": { 64 + "id": { 65 + "name": "id", 66 + "type": "text", 67 + "primaryKey": true, 68 + "notNull": true, 69 + "default": "xata_id()" 70 + }, 71 + "content": { 72 + "name": "content", 73 + "type": "text", 74 + "primaryKey": false, 75 + "notNull": true 76 + }, 77 + "created_at": { 78 + "name": "created_at", 79 + "type": "timestamp", 80 + "primaryKey": false, 81 + "notNull": true, 82 + "default": "now()" 83 + }, 84 + "updated_at": { 85 + "name": "updated_at", 86 + "type": "timestamp", 87 + "primaryKey": false, 88 + "notNull": true, 89 + "default": "now()" 90 + } 91 + }, 92 + "indexes": {}, 93 + "foreignKeys": {}, 94 + "compositePrimaryKeys": {}, 95 + "uniqueConstraints": {}, 96 + "policies": {}, 97 + "checkConstraints": {}, 98 + "isRLSEnabled": false 99 + }, 100 + "public.sandbox_files": { 101 + "name": "sandbox_files", 102 + "schema": "", 103 + "columns": { 104 + "id": { 105 + "name": "id", 106 + "type": "text", 107 + "primaryKey": true, 108 + "notNull": true, 109 + "default": "file_id()" 110 + }, 111 + "sandbox_id": { 112 + "name": "sandbox_id", 113 + "type": "text", 114 + "primaryKey": false, 115 + "notNull": true 116 + }, 117 + "file_id": { 118 + "name": "file_id", 119 + "type": "text", 120 + "primaryKey": false, 121 + "notNull": true 122 + }, 123 + "path": { 124 + "name": "path", 125 + "type": "text", 126 + "primaryKey": false, 127 + "notNull": true 128 + }, 129 + "created_at": { 130 + "name": "created_at", 131 + "type": "timestamp", 132 + "primaryKey": false, 133 + "notNull": true, 134 + "default": "now()" 135 + }, 136 + "updated_at": { 137 + "name": "updated_at", 138 + "type": "timestamp", 139 + "primaryKey": false, 140 + "notNull": true, 141 + "default": "now()" 142 + } 143 + }, 144 + "indexes": { 145 + "unique_sandbox_file_path": { 146 + "name": "unique_sandbox_file_path", 147 + "columns": [ 148 + { 149 + "expression": "sandbox_id", 150 + "isExpression": false, 151 + "asc": true, 152 + "nulls": "last" 153 + }, 154 + { 155 + "expression": "path", 156 + "isExpression": false, 157 + "asc": true, 158 + "nulls": "last" 159 + } 160 + ], 161 + "isUnique": true, 162 + "concurrently": false, 163 + "method": "btree", 164 + "with": {} 165 + } 166 + }, 167 + "foreignKeys": { 168 + "sandbox_files_sandbox_id_sandboxes_id_fk": { 169 + "name": "sandbox_files_sandbox_id_sandboxes_id_fk", 170 + "tableFrom": "sandbox_files", 171 + "tableTo": "sandboxes", 172 + "columnsFrom": [ 173 + "sandbox_id" 174 + ], 175 + "columnsTo": [ 176 + "id" 177 + ], 178 + "onDelete": "no action", 179 + "onUpdate": "no action" 180 + }, 181 + "sandbox_files_file_id_files_id_fk": { 182 + "name": "sandbox_files_file_id_files_id_fk", 183 + "tableFrom": "sandbox_files", 184 + "tableTo": "files", 185 + "columnsFrom": [ 186 + "file_id" 187 + ], 188 + "columnsTo": [ 189 + "id" 190 + ], 191 + "onDelete": "no action", 192 + "onUpdate": "no action" 193 + } 194 + }, 195 + "compositePrimaryKeys": {}, 196 + "uniqueConstraints": {}, 197 + "policies": {}, 198 + "checkConstraints": {}, 199 + "isRLSEnabled": false 200 + }, 201 + "public.sandbox_ports": { 202 + "name": "sandbox_ports", 203 + "schema": "", 204 + "columns": { 205 + "id": { 206 + "name": "id", 207 + "type": "text", 208 + "primaryKey": true, 209 + "notNull": true, 210 + "default": "xata_id()" 211 + }, 212 + "sandbox_id": { 213 + "name": "sandbox_id", 214 + "type": "text", 215 + "primaryKey": false, 216 + "notNull": true 217 + }, 218 + "exposed_port": { 219 + "name": "exposed_port", 220 + "type": "integer", 221 + "primaryKey": false, 222 + "notNull": true 223 + }, 224 + "preview_url": { 225 + "name": "preview_url", 226 + "type": "text", 227 + "primaryKey": false, 228 + "notNull": false 229 + }, 230 + "description": { 231 + "name": "description", 232 + "type": "text", 233 + "primaryKey": false, 234 + "notNull": false 235 + }, 236 + "service_id": { 237 + "name": "service_id", 238 + "type": "text", 239 + "primaryKey": false, 240 + "notNull": false 241 + }, 242 + "created_at": { 243 + "name": "created_at", 244 + "type": "timestamp", 245 + "primaryKey": false, 246 + "notNull": true, 247 + "default": "now()" 248 + }, 249 + "updated_at": { 250 + "name": "updated_at", 251 + "type": "timestamp", 252 + "primaryKey": false, 253 + "notNull": true, 254 + "default": "now()" 255 + } 256 + }, 257 + "indexes": { 258 + "unique_sandbox_port": { 259 + "name": "unique_sandbox_port", 260 + "columns": [ 261 + { 262 + "expression": "sandbox_id", 263 + "isExpression": false, 264 + "asc": true, 265 + "nulls": "last" 266 + }, 267 + { 268 + "expression": "exposed_port", 269 + "isExpression": false, 270 + "asc": true, 271 + "nulls": "last" 272 + } 273 + ], 274 + "isUnique": true, 275 + "concurrently": false, 276 + "method": "btree", 277 + "with": {} 278 + } 279 + }, 280 + "foreignKeys": { 281 + "sandbox_ports_sandbox_id_sandboxes_id_fk": { 282 + "name": "sandbox_ports_sandbox_id_sandboxes_id_fk", 283 + "tableFrom": "sandbox_ports", 284 + "tableTo": "sandboxes", 285 + "columnsFrom": [ 286 + "sandbox_id" 287 + ], 288 + "columnsTo": [ 289 + "id" 290 + ], 291 + "onDelete": "no action", 292 + "onUpdate": "no action" 293 + }, 294 + "sandbox_ports_service_id_services_id_fk": { 295 + "name": "sandbox_ports_service_id_services_id_fk", 296 + "tableFrom": "sandbox_ports", 297 + "tableTo": "services", 298 + "columnsFrom": [ 299 + "service_id" 300 + ], 301 + "columnsTo": [ 302 + "id" 303 + ], 304 + "onDelete": "no action", 305 + "onUpdate": "no action" 306 + } 307 + }, 308 + "compositePrimaryKeys": {}, 309 + "uniqueConstraints": {}, 310 + "policies": {}, 311 + "checkConstraints": {}, 312 + "isRLSEnabled": false 313 + }, 314 + "public.sandbox_secrets": { 315 + "name": "sandbox_secrets", 316 + "schema": "", 317 + "columns": { 318 + "id": { 319 + "name": "id", 320 + "type": "text", 321 + "primaryKey": true, 322 + "notNull": true, 323 + "default": "xata_id()" 324 + }, 325 + "sandbox_id": { 326 + "name": "sandbox_id", 327 + "type": "text", 328 + "primaryKey": false, 329 + "notNull": true 330 + }, 331 + "secret_id": { 332 + "name": "secret_id", 333 + "type": "text", 334 + "primaryKey": false, 335 + "notNull": true 336 + }, 337 + "name": { 338 + "name": "name", 339 + "type": "text", 340 + "primaryKey": false, 341 + "notNull": false 342 + }, 343 + "created_at": { 344 + "name": "created_at", 345 + "type": "timestamp", 346 + "primaryKey": false, 347 + "notNull": true, 348 + "default": "now()" 349 + }, 350 + "updated_at": { 351 + "name": "updated_at", 352 + "type": "timestamp", 353 + "primaryKey": false, 354 + "notNull": true, 355 + "default": "now()" 356 + } 357 + }, 358 + "indexes": { 359 + "unique_sandbox_secret_by_name": { 360 + "name": "unique_sandbox_secret_by_name", 361 + "columns": [ 362 + { 363 + "expression": "sandbox_id", 364 + "isExpression": false, 365 + "asc": true, 366 + "nulls": "last" 367 + }, 368 + { 369 + "expression": "name", 370 + "isExpression": false, 371 + "asc": true, 372 + "nulls": "last" 373 + } 374 + ], 375 + "isUnique": true, 376 + "concurrently": false, 377 + "method": "btree", 378 + "with": {} 379 + } 380 + }, 381 + "foreignKeys": { 382 + "sandbox_secrets_sandbox_id_sandboxes_id_fk": { 383 + "name": "sandbox_secrets_sandbox_id_sandboxes_id_fk", 384 + "tableFrom": "sandbox_secrets", 385 + "tableTo": "sandboxes", 386 + "columnsFrom": [ 387 + "sandbox_id" 388 + ], 389 + "columnsTo": [ 390 + "id" 391 + ], 392 + "onDelete": "no action", 393 + "onUpdate": "no action" 394 + }, 395 + "sandbox_secrets_secret_id_secrets_id_fk": { 396 + "name": "sandbox_secrets_secret_id_secrets_id_fk", 397 + "tableFrom": "sandbox_secrets", 398 + "tableTo": "secrets", 399 + "columnsFrom": [ 400 + "secret_id" 401 + ], 402 + "columnsTo": [ 403 + "id" 404 + ], 405 + "onDelete": "no action", 406 + "onUpdate": "no action" 407 + } 408 + }, 409 + "compositePrimaryKeys": {}, 410 + "uniqueConstraints": {}, 411 + "policies": {}, 412 + "checkConstraints": {}, 413 + "isRLSEnabled": false 414 + }, 415 + "public.sandbox_variables": { 416 + "name": "sandbox_variables", 417 + "schema": "", 418 + "columns": { 419 + "id": { 420 + "name": "id", 421 + "type": "text", 422 + "primaryKey": true, 423 + "notNull": true, 424 + "default": "xata_id()" 425 + }, 426 + "sandbox_id": { 427 + "name": "sandbox_id", 428 + "type": "text", 429 + "primaryKey": false, 430 + "notNull": true 431 + }, 432 + "variable_id": { 433 + "name": "variable_id", 434 + "type": "text", 435 + "primaryKey": false, 436 + "notNull": true 437 + }, 438 + "name": { 439 + "name": "name", 440 + "type": "text", 441 + "primaryKey": false, 442 + "notNull": true 443 + }, 444 + "created_at": { 445 + "name": "created_at", 446 + "type": "timestamp", 447 + "primaryKey": false, 448 + "notNull": true, 449 + "default": "now()" 450 + }, 451 + "updated_at": { 452 + "name": "updated_at", 453 + "type": "timestamp", 454 + "primaryKey": false, 455 + "notNull": true, 456 + "default": "now()" 457 + } 458 + }, 459 + "indexes": { 460 + "unique_sandbox_variables_by_name": { 461 + "name": "unique_sandbox_variables_by_name", 462 + "columns": [ 463 + { 464 + "expression": "sandbox_id", 465 + "isExpression": false, 466 + "asc": true, 467 + "nulls": "last" 468 + }, 469 + { 470 + "expression": "name", 471 + "isExpression": false, 472 + "asc": true, 473 + "nulls": "last" 474 + } 475 + ], 476 + "isUnique": true, 477 + "concurrently": false, 478 + "method": "btree", 479 + "with": {} 480 + } 481 + }, 482 + "foreignKeys": { 483 + "sandbox_variables_sandbox_id_sandboxes_id_fk": { 484 + "name": "sandbox_variables_sandbox_id_sandboxes_id_fk", 485 + "tableFrom": "sandbox_variables", 486 + "tableTo": "sandboxes", 487 + "columnsFrom": [ 488 + "sandbox_id" 489 + ], 490 + "columnsTo": [ 491 + "id" 492 + ], 493 + "onDelete": "no action", 494 + "onUpdate": "no action" 495 + }, 496 + "sandbox_variables_variable_id_variables_id_fk": { 497 + "name": "sandbox_variables_variable_id_variables_id_fk", 498 + "tableFrom": "sandbox_variables", 499 + "tableTo": "variables", 500 + "columnsFrom": [ 501 + "variable_id" 502 + ], 503 + "columnsTo": [ 504 + "id" 505 + ], 506 + "onDelete": "no action", 507 + "onUpdate": "no action" 508 + } 509 + }, 510 + "compositePrimaryKeys": {}, 511 + "uniqueConstraints": {}, 512 + "policies": {}, 513 + "checkConstraints": {}, 514 + "isRLSEnabled": false 515 + }, 516 + "public.sandbox_volumes": { 517 + "name": "sandbox_volumes", 518 + "schema": "", 519 + "columns": { 520 + "id": { 521 + "name": "id", 522 + "type": "text", 523 + "primaryKey": true, 524 + "notNull": true, 525 + "default": "volume_id()" 526 + }, 527 + "sandbox_id": { 528 + "name": "sandbox_id", 529 + "type": "text", 530 + "primaryKey": false, 531 + "notNull": true 532 + }, 533 + "volume_id": { 534 + "name": "volume_id", 535 + "type": "text", 536 + "primaryKey": false, 537 + "notNull": true 538 + }, 539 + "name": { 540 + "name": "name", 541 + "type": "text", 542 + "primaryKey": false, 543 + "notNull": false 544 + }, 545 + "path": { 546 + "name": "path", 547 + "type": "text", 548 + "primaryKey": false, 549 + "notNull": true 550 + }, 551 + "created_at": { 552 + "name": "created_at", 553 + "type": "timestamp", 554 + "primaryKey": false, 555 + "notNull": true, 556 + "default": "now()" 557 + }, 558 + "updated_at": { 559 + "name": "updated_at", 560 + "type": "timestamp", 561 + "primaryKey": false, 562 + "notNull": true, 563 + "default": "now()" 564 + } 565 + }, 566 + "indexes": { 567 + "unique_sandbox_volume_path": { 568 + "name": "unique_sandbox_volume_path", 569 + "columns": [ 570 + { 571 + "expression": "sandbox_id", 572 + "isExpression": false, 573 + "asc": true, 574 + "nulls": "last" 575 + }, 576 + { 577 + "expression": "path", 578 + "isExpression": false, 579 + "asc": true, 580 + "nulls": "last" 581 + } 582 + ], 583 + "isUnique": true, 584 + "concurrently": false, 585 + "method": "btree", 586 + "with": {} 587 + } 588 + }, 589 + "foreignKeys": { 590 + "sandbox_volumes_sandbox_id_sandboxes_id_fk": { 591 + "name": "sandbox_volumes_sandbox_id_sandboxes_id_fk", 592 + "tableFrom": "sandbox_volumes", 593 + "tableTo": "sandboxes", 594 + "columnsFrom": [ 595 + "sandbox_id" 596 + ], 597 + "columnsTo": [ 598 + "id" 599 + ], 600 + "onDelete": "no action", 601 + "onUpdate": "no action" 602 + }, 603 + "sandbox_volumes_volume_id_volumes_id_fk": { 604 + "name": "sandbox_volumes_volume_id_volumes_id_fk", 605 + "tableFrom": "sandbox_volumes", 606 + "tableTo": "volumes", 607 + "columnsFrom": [ 608 + "volume_id" 609 + ], 610 + "columnsTo": [ 611 + "id" 612 + ], 613 + "onDelete": "no action", 614 + "onUpdate": "no action" 615 + } 616 + }, 617 + "compositePrimaryKeys": {}, 618 + "uniqueConstraints": {}, 619 + "policies": {}, 620 + "checkConstraints": {}, 621 + "isRLSEnabled": false 622 + }, 623 + "public.sandboxes": { 624 + "name": "sandboxes", 625 + "schema": "", 626 + "columns": { 627 + "id": { 628 + "name": "id", 629 + "type": "text", 630 + "primaryKey": true, 631 + "notNull": true, 632 + "default": "sandbox_id()" 633 + }, 634 + "base": { 635 + "name": "base", 636 + "type": "text", 637 + "primaryKey": false, 638 + "notNull": false 639 + }, 640 + "name": { 641 + "name": "name", 642 + "type": "text", 643 + "primaryKey": false, 644 + "notNull": true 645 + }, 646 + "display_name": { 647 + "name": "display_name", 648 + "type": "text", 649 + "primaryKey": false, 650 + "notNull": false 651 + }, 652 + "uri": { 653 + "name": "uri", 654 + "type": "text", 655 + "primaryKey": false, 656 + "notNull": false 657 + }, 658 + "cid": { 659 + "name": "cid", 660 + "type": "text", 661 + "primaryKey": false, 662 + "notNull": false 663 + }, 664 + "repo": { 665 + "name": "repo", 666 + "type": "text", 667 + "primaryKey": false, 668 + "notNull": false 669 + }, 670 + "provider": { 671 + "name": "provider", 672 + "type": "text", 673 + "primaryKey": false, 674 + "notNull": true, 675 + "default": "'cloudflare'" 676 + }, 677 + "description": { 678 + "name": "description", 679 + "type": "text", 680 + "primaryKey": false, 681 + "notNull": false 682 + }, 683 + "topics": { 684 + "name": "topics", 685 + "type": "text[]", 686 + "primaryKey": false, 687 + "notNull": false 688 + }, 689 + "logo": { 690 + "name": "logo", 691 + "type": "text", 692 + "primaryKey": false, 693 + "notNull": false 694 + }, 695 + "readme": { 696 + "name": "readme", 697 + "type": "text", 698 + "primaryKey": false, 699 + "notNull": false 700 + }, 701 + "public_key": { 702 + "name": "public_key", 703 + "type": "text", 704 + "primaryKey": false, 705 + "notNull": true 706 + }, 707 + "user_id": { 708 + "name": "user_id", 709 + "type": "text", 710 + "primaryKey": false, 711 + "notNull": false 712 + }, 713 + "instance_type": { 714 + "name": "instance_type", 715 + "type": "text", 716 + "primaryKey": false, 717 + "notNull": false 718 + }, 719 + "vcpus": { 720 + "name": "vcpus", 721 + "type": "integer", 722 + "primaryKey": false, 723 + "notNull": false 724 + }, 725 + "memory": { 726 + "name": "memory", 727 + "type": "integer", 728 + "primaryKey": false, 729 + "notNull": false 730 + }, 731 + "disk": { 732 + "name": "disk", 733 + "type": "integer", 734 + "primaryKey": false, 735 + "notNull": false 736 + }, 737 + "status": { 738 + "name": "status", 739 + "type": "text", 740 + "primaryKey": false, 741 + "notNull": true 742 + }, 743 + "keep_alive": { 744 + "name": "keep_alive", 745 + "type": "boolean", 746 + "primaryKey": false, 747 + "notNull": true, 748 + "default": false 749 + }, 750 + "sleep_after": { 751 + "name": "sleep_after", 752 + "type": "text", 753 + "primaryKey": false, 754 + "notNull": false 755 + }, 756 + "sandbox_id": { 757 + "name": "sandbox_id", 758 + "type": "text", 759 + "primaryKey": false, 760 + "notNull": false 761 + }, 762 + "installs": { 763 + "name": "installs", 764 + "type": "integer", 765 + "primaryKey": false, 766 + "notNull": true, 767 + "default": 0 768 + }, 769 + "started_at": { 770 + "name": "started_at", 771 + "type": "timestamp", 772 + "primaryKey": false, 773 + "notNull": false 774 + }, 775 + "created_at": { 776 + "name": "created_at", 777 + "type": "timestamp", 778 + "primaryKey": false, 779 + "notNull": true, 780 + "default": "now()" 781 + }, 782 + "updated_at": { 783 + "name": "updated_at", 784 + "type": "timestamp", 785 + "primaryKey": false, 786 + "notNull": true, 787 + "default": "now()" 788 + } 789 + }, 790 + "indexes": {}, 791 + "foreignKeys": { 792 + "sandboxes_user_id_users_id_fk": { 793 + "name": "sandboxes_user_id_users_id_fk", 794 + "tableFrom": "sandboxes", 795 + "tableTo": "users", 796 + "columnsFrom": [ 797 + "user_id" 798 + ], 799 + "columnsTo": [ 800 + "id" 801 + ], 802 + "onDelete": "no action", 803 + "onUpdate": "no action" 804 + } 805 + }, 806 + "compositePrimaryKeys": {}, 807 + "uniqueConstraints": { 808 + "sandboxes_name_unique": { 809 + "name": "sandboxes_name_unique", 810 + "nullsNotDistinct": false, 811 + "columns": [ 812 + "name" 813 + ] 814 + }, 815 + "sandboxes_uri_unique": { 816 + "name": "sandboxes_uri_unique", 817 + "nullsNotDistinct": false, 818 + "columns": [ 819 + "uri" 820 + ] 821 + }, 822 + "sandboxes_cid_unique": { 823 + "name": "sandboxes_cid_unique", 824 + "nullsNotDistinct": false, 825 + "columns": [ 826 + "cid" 827 + ] 828 + } 829 + }, 830 + "policies": {}, 831 + "checkConstraints": {}, 832 + "isRLSEnabled": false 833 + }, 834 + "public.secrets": { 835 + "name": "secrets", 836 + "schema": "", 837 + "columns": { 838 + "id": { 839 + "name": "id", 840 + "type": "text", 841 + "primaryKey": true, 842 + "notNull": true, 843 + "default": "secret_id()" 844 + }, 845 + "name": { 846 + "name": "name", 847 + "type": "text", 848 + "primaryKey": false, 849 + "notNull": true 850 + }, 851 + "value": { 852 + "name": "value", 853 + "type": "text", 854 + "primaryKey": false, 855 + "notNull": true 856 + }, 857 + "redacted": { 858 + "name": "redacted", 859 + "type": "text", 860 + "primaryKey": false, 861 + "notNull": false 862 + }, 863 + "created_at": { 864 + "name": "created_at", 865 + "type": "timestamp", 866 + "primaryKey": false, 867 + "notNull": true, 868 + "default": "now()" 869 + } 870 + }, 871 + "indexes": {}, 872 + "foreignKeys": {}, 873 + "compositePrimaryKeys": {}, 874 + "uniqueConstraints": {}, 875 + "policies": {}, 876 + "checkConstraints": {}, 877 + "isRLSEnabled": false 878 + }, 879 + "public.snapshots": { 880 + "name": "snapshots", 881 + "schema": "", 882 + "columns": { 883 + "id": { 884 + "name": "id", 885 + "type": "text", 886 + "primaryKey": true, 887 + "notNull": true, 888 + "default": "snapshot_id()" 889 + }, 890 + "slug": { 891 + "name": "slug", 892 + "type": "text", 893 + "primaryKey": false, 894 + "notNull": true 895 + }, 896 + "created_at": { 897 + "name": "created_at", 898 + "type": "timestamp", 899 + "primaryKey": false, 900 + "notNull": true, 901 + "default": "now()" 902 + } 903 + }, 904 + "indexes": {}, 905 + "foreignKeys": {}, 906 + "compositePrimaryKeys": {}, 907 + "uniqueConstraints": { 908 + "snapshots_slug_unique": { 909 + "name": "snapshots_slug_unique", 910 + "nullsNotDistinct": false, 911 + "columns": [ 912 + "slug" 913 + ] 914 + } 915 + }, 916 + "policies": {}, 917 + "checkConstraints": {}, 918 + "isRLSEnabled": false 919 + }, 920 + "public.ssh_keys": { 921 + "name": "ssh_keys", 922 + "schema": "", 923 + "columns": { 924 + "id": { 925 + "name": "id", 926 + "type": "text", 927 + "primaryKey": true, 928 + "notNull": true, 929 + "default": "xata_id()" 930 + }, 931 + "sandbox_id": { 932 + "name": "sandbox_id", 933 + "type": "text", 934 + "primaryKey": false, 935 + "notNull": true 936 + }, 937 + "public_key": { 938 + "name": "public_key", 939 + "type": "text", 940 + "primaryKey": false, 941 + "notNull": true 942 + }, 943 + "private_key": { 944 + "name": "private_key", 945 + "type": "text", 946 + "primaryKey": false, 947 + "notNull": true 948 + }, 949 + "redacted": { 950 + "name": "redacted", 951 + "type": "text", 952 + "primaryKey": false, 953 + "notNull": false 954 + }, 955 + "created_at": { 956 + "name": "created_at", 957 + "type": "timestamp", 958 + "primaryKey": false, 959 + "notNull": true, 960 + "default": "now()" 961 + } 962 + }, 963 + "indexes": { 964 + "unique_sandbox_ssh_key": { 965 + "name": "unique_sandbox_ssh_key", 966 + "columns": [ 967 + { 968 + "expression": "public_key", 969 + "isExpression": false, 970 + "asc": true, 971 + "nulls": "last" 972 + }, 973 + { 974 + "expression": "sandbox_id", 975 + "isExpression": false, 976 + "asc": true, 977 + "nulls": "last" 978 + } 979 + ], 980 + "isUnique": true, 981 + "concurrently": false, 982 + "method": "btree", 983 + "with": {} 984 + } 985 + }, 986 + "foreignKeys": { 987 + "ssh_keys_sandbox_id_sandboxes_id_fk": { 988 + "name": "ssh_keys_sandbox_id_sandboxes_id_fk", 989 + "tableFrom": "ssh_keys", 990 + "tableTo": "sandboxes", 991 + "columnsFrom": [ 992 + "sandbox_id" 993 + ], 994 + "columnsTo": [ 995 + "id" 996 + ], 997 + "onDelete": "no action", 998 + "onUpdate": "no action" 999 + } 1000 + }, 1001 + "compositePrimaryKeys": {}, 1002 + "uniqueConstraints": {}, 1003 + "policies": {}, 1004 + "checkConstraints": {}, 1005 + "isRLSEnabled": false 1006 + }, 1007 + "public.tailscale_auth_keys": { 1008 + "name": "tailscale_auth_keys", 1009 + "schema": "", 1010 + "columns": { 1011 + "id": { 1012 + "name": "id", 1013 + "type": "text", 1014 + "primaryKey": true, 1015 + "notNull": true, 1016 + "default": "xata_id()" 1017 + }, 1018 + "sandbox_id": { 1019 + "name": "sandbox_id", 1020 + "type": "text", 1021 + "primaryKey": false, 1022 + "notNull": true 1023 + }, 1024 + "auth_key": { 1025 + "name": "auth_key", 1026 + "type": "text", 1027 + "primaryKey": false, 1028 + "notNull": true 1029 + }, 1030 + "redacted": { 1031 + "name": "redacted", 1032 + "type": "text", 1033 + "primaryKey": false, 1034 + "notNull": true 1035 + }, 1036 + "created_at": { 1037 + "name": "created_at", 1038 + "type": "timestamp", 1039 + "primaryKey": false, 1040 + "notNull": true, 1041 + "default": "now()" 1042 + } 1043 + }, 1044 + "indexes": {}, 1045 + "foreignKeys": { 1046 + "tailscale_auth_keys_sandbox_id_sandboxes_id_fk": { 1047 + "name": "tailscale_auth_keys_sandbox_id_sandboxes_id_fk", 1048 + "tableFrom": "tailscale_auth_keys", 1049 + "tableTo": "sandboxes", 1050 + "columnsFrom": [ 1051 + "sandbox_id" 1052 + ], 1053 + "columnsTo": [ 1054 + "id" 1055 + ], 1056 + "onDelete": "no action", 1057 + "onUpdate": "no action" 1058 + } 1059 + }, 1060 + "compositePrimaryKeys": {}, 1061 + "uniqueConstraints": {}, 1062 + "policies": {}, 1063 + "checkConstraints": {}, 1064 + "isRLSEnabled": false 1065 + }, 1066 + "public.users": { 1067 + "name": "users", 1068 + "schema": "", 1069 + "columns": { 1070 + "id": { 1071 + "name": "id", 1072 + "type": "text", 1073 + "primaryKey": true, 1074 + "notNull": true, 1075 + "default": "xata_id()" 1076 + }, 1077 + "did": { 1078 + "name": "did", 1079 + "type": "text", 1080 + "primaryKey": false, 1081 + "notNull": true 1082 + }, 1083 + "display_name": { 1084 + "name": "display_name", 1085 + "type": "text", 1086 + "primaryKey": false, 1087 + "notNull": false 1088 + }, 1089 + "handle": { 1090 + "name": "handle", 1091 + "type": "text", 1092 + "primaryKey": false, 1093 + "notNull": true 1094 + }, 1095 + "avatar": { 1096 + "name": "avatar", 1097 + "type": "text", 1098 + "primaryKey": false, 1099 + "notNull": false 1100 + }, 1101 + "created_at": { 1102 + "name": "created_at", 1103 + "type": "timestamp", 1104 + "primaryKey": false, 1105 + "notNull": true, 1106 + "default": "now()" 1107 + }, 1108 + "updated_at": { 1109 + "name": "updated_at", 1110 + "type": "timestamp", 1111 + "primaryKey": false, 1112 + "notNull": true, 1113 + "default": "now()" 1114 + } 1115 + }, 1116 + "indexes": {}, 1117 + "foreignKeys": {}, 1118 + "compositePrimaryKeys": {}, 1119 + "uniqueConstraints": { 1120 + "users_did_unique": { 1121 + "name": "users_did_unique", 1122 + "nullsNotDistinct": false, 1123 + "columns": [ 1124 + "did" 1125 + ] 1126 + }, 1127 + "users_handle_unique": { 1128 + "name": "users_handle_unique", 1129 + "nullsNotDistinct": false, 1130 + "columns": [ 1131 + "handle" 1132 + ] 1133 + } 1134 + }, 1135 + "policies": {}, 1136 + "checkConstraints": {}, 1137 + "isRLSEnabled": false 1138 + }, 1139 + "public.variables": { 1140 + "name": "variables", 1141 + "schema": "", 1142 + "columns": { 1143 + "id": { 1144 + "name": "id", 1145 + "type": "text", 1146 + "primaryKey": true, 1147 + "notNull": true, 1148 + "default": "variable_id()" 1149 + }, 1150 + "name": { 1151 + "name": "name", 1152 + "type": "text", 1153 + "primaryKey": false, 1154 + "notNull": true 1155 + }, 1156 + "value": { 1157 + "name": "value", 1158 + "type": "text", 1159 + "primaryKey": false, 1160 + "notNull": true 1161 + }, 1162 + "created_at": { 1163 + "name": "created_at", 1164 + "type": "timestamp", 1165 + "primaryKey": false, 1166 + "notNull": true, 1167 + "default": "now()" 1168 + }, 1169 + "updated_at": { 1170 + "name": "updated_at", 1171 + "type": "timestamp", 1172 + "primaryKey": false, 1173 + "notNull": true, 1174 + "default": "now()" 1175 + } 1176 + }, 1177 + "indexes": {}, 1178 + "foreignKeys": {}, 1179 + "compositePrimaryKeys": {}, 1180 + "uniqueConstraints": {}, 1181 + "policies": {}, 1182 + "checkConstraints": {}, 1183 + "isRLSEnabled": false 1184 + }, 1185 + "public.volumes": { 1186 + "name": "volumes", 1187 + "schema": "", 1188 + "columns": { 1189 + "id": { 1190 + "name": "id", 1191 + "type": "text", 1192 + "primaryKey": true, 1193 + "notNull": true, 1194 + "default": "volume_id()" 1195 + }, 1196 + "slug": { 1197 + "name": "slug", 1198 + "type": "text", 1199 + "primaryKey": false, 1200 + "notNull": true 1201 + }, 1202 + "size": { 1203 + "name": "size", 1204 + "type": "integer", 1205 + "primaryKey": false, 1206 + "notNull": true 1207 + }, 1208 + "size_unit": { 1209 + "name": "size_unit", 1210 + "type": "text", 1211 + "primaryKey": false, 1212 + "notNull": true 1213 + }, 1214 + "created_at": { 1215 + "name": "created_at", 1216 + "type": "timestamp", 1217 + "primaryKey": false, 1218 + "notNull": true, 1219 + "default": "now()" 1220 + }, 1221 + "updated_at": { 1222 + "name": "updated_at", 1223 + "type": "timestamp", 1224 + "primaryKey": false, 1225 + "notNull": true, 1226 + "default": "now()" 1227 + } 1228 + }, 1229 + "indexes": {}, 1230 + "foreignKeys": {}, 1231 + "compositePrimaryKeys": {}, 1232 + "uniqueConstraints": { 1233 + "volumes_slug_unique": { 1234 + "name": "volumes_slug_unique", 1235 + "nullsNotDistinct": false, 1236 + "columns": [ 1237 + "slug" 1238 + ] 1239 + } 1240 + }, 1241 + "policies": {}, 1242 + "checkConstraints": {}, 1243 + "isRLSEnabled": false 1244 + }, 1245 + "public.integrations": { 1246 + "name": "integrations", 1247 + "schema": "", 1248 + "columns": { 1249 + "id": { 1250 + "name": "id", 1251 + "type": "text", 1252 + "primaryKey": true, 1253 + "notNull": true, 1254 + "default": "xata_id()" 1255 + }, 1256 + "sandbox_id": { 1257 + "name": "sandbox_id", 1258 + "type": "text", 1259 + "primaryKey": false, 1260 + "notNull": true 1261 + }, 1262 + "name": { 1263 + "name": "name", 1264 + "type": "text", 1265 + "primaryKey": false, 1266 + "notNull": true 1267 + }, 1268 + "description": { 1269 + "name": "description", 1270 + "type": "text", 1271 + "primaryKey": false, 1272 + "notNull": false 1273 + }, 1274 + "webhook_url": { 1275 + "name": "webhook_url", 1276 + "type": "text", 1277 + "primaryKey": false, 1278 + "notNull": true 1279 + }, 1280 + "created_at": { 1281 + "name": "created_at", 1282 + "type": "timestamp", 1283 + "primaryKey": false, 1284 + "notNull": true, 1285 + "default": "now()" 1286 + } 1287 + }, 1288 + "indexes": { 1289 + "unique_sandbox_integration": { 1290 + "name": "unique_sandbox_integration", 1291 + "columns": [ 1292 + { 1293 + "expression": "sandbox_id", 1294 + "isExpression": false, 1295 + "asc": true, 1296 + "nulls": "last" 1297 + }, 1298 + { 1299 + "expression": "name", 1300 + "isExpression": false, 1301 + "asc": true, 1302 + "nulls": "last" 1303 + } 1304 + ], 1305 + "isUnique": true, 1306 + "concurrently": false, 1307 + "method": "btree", 1308 + "with": {} 1309 + } 1310 + }, 1311 + "foreignKeys": { 1312 + "integrations_sandbox_id_sandboxes_id_fk": { 1313 + "name": "integrations_sandbox_id_sandboxes_id_fk", 1314 + "tableFrom": "integrations", 1315 + "tableTo": "sandboxes", 1316 + "columnsFrom": [ 1317 + "sandbox_id" 1318 + ], 1319 + "columnsTo": [ 1320 + "id" 1321 + ], 1322 + "onDelete": "no action", 1323 + "onUpdate": "no action" 1324 + } 1325 + }, 1326 + "compositePrimaryKeys": {}, 1327 + "uniqueConstraints": {}, 1328 + "policies": {}, 1329 + "checkConstraints": {}, 1330 + "isRLSEnabled": false 1331 + }, 1332 + "public.services": { 1333 + "name": "services", 1334 + "schema": "", 1335 + "columns": { 1336 + "id": { 1337 + "name": "id", 1338 + "type": "text", 1339 + "primaryKey": true, 1340 + "notNull": true, 1341 + "default": "xata_id()" 1342 + }, 1343 + "sandbox_id": { 1344 + "name": "sandbox_id", 1345 + "type": "text", 1346 + "primaryKey": false, 1347 + "notNull": true 1348 + }, 1349 + "name": { 1350 + "name": "name", 1351 + "type": "text", 1352 + "primaryKey": false, 1353 + "notNull": true 1354 + }, 1355 + "command": { 1356 + "name": "command", 1357 + "type": "text", 1358 + "primaryKey": false, 1359 + "notNull": true 1360 + }, 1361 + "description": { 1362 + "name": "description", 1363 + "type": "text", 1364 + "primaryKey": false, 1365 + "notNull": false 1366 + }, 1367 + "created_at": { 1368 + "name": "created_at", 1369 + "type": "timestamp", 1370 + "primaryKey": false, 1371 + "notNull": true, 1372 + "default": "now()" 1373 + }, 1374 + "updated_at": { 1375 + "name": "updated_at", 1376 + "type": "timestamp", 1377 + "primaryKey": false, 1378 + "notNull": true, 1379 + "default": "now()" 1380 + } 1381 + }, 1382 + "indexes": { 1383 + "unique_sandbox_service": { 1384 + "name": "unique_sandbox_service", 1385 + "columns": [ 1386 + { 1387 + "expression": "name", 1388 + "isExpression": false, 1389 + "asc": true, 1390 + "nulls": "last" 1391 + }, 1392 + { 1393 + "expression": "sandbox_id", 1394 + "isExpression": false, 1395 + "asc": true, 1396 + "nulls": "last" 1397 + } 1398 + ], 1399 + "isUnique": true, 1400 + "concurrently": false, 1401 + "method": "btree", 1402 + "with": {} 1403 + } 1404 + }, 1405 + "foreignKeys": { 1406 + "services_sandbox_id_sandboxes_id_fk": { 1407 + "name": "services_sandbox_id_sandboxes_id_fk", 1408 + "tableFrom": "services", 1409 + "tableTo": "sandboxes", 1410 + "columnsFrom": [ 1411 + "sandbox_id" 1412 + ], 1413 + "columnsTo": [ 1414 + "id" 1415 + ], 1416 + "onDelete": "no action", 1417 + "onUpdate": "no action" 1418 + } 1419 + }, 1420 + "compositePrimaryKeys": {}, 1421 + "uniqueConstraints": {}, 1422 + "policies": {}, 1423 + "checkConstraints": {}, 1424 + "isRLSEnabled": false 1425 + } 1426 + }, 1427 + "enums": {}, 1428 + "schemas": {}, 1429 + "sequences": {}, 1430 + "roles": {}, 1431 + "policies": {}, 1432 + "views": {}, 1433 + "_meta": { 1434 + "columns": {}, 1435 + "schemas": {}, 1436 + "tables": {} 1437 + } 1438 + }
+7
apps/cf-sandbox/drizzle/meta/_journal.json
··· 225 225 "when": 1774062945617, 226 226 "tag": "0031_stormy_retro_girl", 227 227 "breakpoints": true 228 + }, 229 + { 230 + "idx": 32, 231 + "version": "7", 232 + "when": 1774689827058, 233 + "tag": "0032_happy_leech", 234 + "breakpoints": true 228 235 } 229 236 ] 230 237 }
+2
apps/cf-sandbox/src/schema/sandbox-ports.ts
··· 7 7 integer, 8 8 } from "drizzle-orm/pg-core"; 9 9 import sandboxes from "./sandboxes"; 10 + import services from "./services"; 10 11 11 12 const sandboxPorts = pgTable( 12 13 "sandbox_ports", ··· 20 21 exposedPort: integer("exposed_port").notNull(), 21 22 previewUrl: text("preview_url"), 22 23 description: text("description"), 24 + serviceId: text("service_id").references(() => services.id), 23 25 createdAt: timestamp("created_at").defaultNow().notNull(), 24 26 updatedAt: timestamp("updated_at").defaultNow().notNull(), 25 27 },
+26
apps/cf-sandbox/src/schema/services.ts
··· 1 + import { type InferInsertModel, type InferSelectModel, sql } from "drizzle-orm"; 2 + import { pgTable, text, timestamp, uniqueIndex } from "drizzle-orm/pg-core"; 3 + import sandboxes from "./sandboxes"; 4 + 5 + const services = pgTable( 6 + "services", 7 + { 8 + id: text("id") 9 + .primaryKey() 10 + .default(sql`xata_id()`), 11 + sandboxId: text("sandbox_id") 12 + .notNull() 13 + .references(() => sandboxes.id), 14 + name: text("name").notNull(), 15 + command: text("command").notNull(), 16 + description: text("description"), 17 + createdAt: timestamp("created_at").defaultNow().notNull(), 18 + updatedAt: timestamp("updated_at").defaultNow().notNull(), 19 + }, 20 + (t) => [uniqueIndex("unique_sandbox_service").on(t.name, t.sandboxId)], 21 + ); 22 + 23 + export type SelectService = InferSelectModel<typeof services>; 24 + export type InsertService = InferInsertModel<typeof services>; 25 + 26 + export default services;
+2
apps/sandbox/src/schema/sandbox-ports.ts
··· 7 7 integer, 8 8 } from "drizzle-orm/pg-core"; 9 9 import sandboxes from "./sandboxes.ts"; 10 + import services from "./services.ts"; 10 11 11 12 const sandboxPorts = pgTable( 12 13 "sandbox_ports", ··· 20 21 exposedPort: integer("exposed_port").notNull(), 21 22 previewUrl: text("preview_url"), 22 23 description: text("description"), 24 + serviceId: text("service_id").references(() => services.id), 23 25 createdAt: timestamp("created_at").defaultNow().notNull(), 24 26 updatedAt: timestamp("updated_at").defaultNow().notNull(), 25 27 },
+26
apps/sandbox/src/schema/services.ts
··· 1 + import { type InferInsertModel, type InferSelectModel, sql } from "drizzle-orm"; 2 + import { pgTable, text, timestamp, uniqueIndex } from "drizzle-orm/pg-core"; 3 + import sandboxes from "./sandboxes.ts"; 4 + 5 + const services = pgTable( 6 + "services", 7 + { 8 + id: text("id") 9 + .primaryKey() 10 + .default(sql`xata_id()`), 11 + sandboxId: text("sandbox_id") 12 + .notNull() 13 + .references(() => sandboxes.id), 14 + name: text("name").notNull(), 15 + command: text("command").notNull(), 16 + description: text("description"), 17 + createdAt: timestamp("created_at").defaultNow().notNull(), 18 + updatedAt: timestamp("updated_at").defaultNow().notNull(), 19 + }, 20 + (t) => [uniqueIndex("unique_sandbox_service").on(t.name, t.sandboxId)], 21 + ); 22 + 23 + export type SelectService = InferSelectModel<typeof services>; 24 + export type InsertService = InferInsertModel<typeof services>; 25 + 26 + export default services;