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 Tailscale Auth Key support and SSH updates

+6142 -231
+10 -6
apps/api/lexicons/sandbox/defs.json
··· 337 337 } 338 338 } 339 339 }, 340 - "tailscaleTokenView": { 340 + "tailscaleAuthKeyView": { 341 341 "type": "object", 342 342 "properties": { 343 343 "id": { 344 344 "type": "string", 345 - "description": "Unique identifier of the Tailscale token." 345 + "description": "Unique identifier of the Tailscale Auth Key." 346 346 }, 347 - "token": { 347 + "authKey": { 348 348 "type": "string", 349 - "description": "The Tailscale auth token (redacted in API responses)" 349 + "description": "The Tailscale auth key (redacted in API responses)" 350 + }, 351 + "redacted": { 352 + "type": "string", 353 + "description": "The redacted Auth Key." 350 354 }, 351 355 "createdAt": { 352 356 "type": "string", 353 - "description": "The timestamp when the Tailscale token was created.", 357 + "description": "The timestamp when the Tailscale Auth Key was created.", 354 358 "format": "datetime" 355 359 }, 356 360 "updatedAt": { 357 361 "type": "string", 358 - "description": "The timestamp when the Tailscale token was last updated.", 362 + "description": "The timestamp when the Tailscale Auth Key was last updated.", 359 363 "format": "datetime" 360 364 } 361 365 }
+29
apps/api/lexicons/sandbox/getTailscaleAuthKey.json
··· 1 + { 2 + "lexicon": 1, 3 + "id": "io.pocketenv.sandbox.getTailscaleAuthKey", 4 + "defs": { 5 + "main": { 6 + "type": "query", 7 + "description": "Get the Tailscale token for a sandbox.", 8 + "parameters": { 9 + "type": "params", 10 + "required": [ 11 + "id" 12 + ], 13 + "properties": { 14 + "id": { 15 + "type": "string", 16 + "description": "The sandbox ID." 17 + } 18 + } 19 + }, 20 + "output": { 21 + "encoding": "application/json", 22 + "schema": { 23 + "type": "ref", 24 + "ref": "io.pocketenv.sandbox.defs#tailscaleAuthKeyView" 25 + } 26 + } 27 + } 28 + } 29 + }
+4
apps/api/lexicons/sandbox/putSshKeys.json
··· 26 26 "publicKey": { 27 27 "type": "string", 28 28 "description": "The public SSH key." 29 + }, 30 + "redacted": { 31 + "type": "string", 32 + "description": "The redacted SSH key." 29 33 } 30 34 } 31 35 }
+41
apps/api/lexicons/sandbox/putTailscaleAuthKey.json
··· 1 + { 2 + "lexicon": 1, 3 + "id": "io.pocketenv.sandbox.putTailscaleAuthKey", 4 + "defs": { 5 + "main": { 6 + "type": "procedure", 7 + "description": "Store a Tailscale Auth Key for the sandbox. This Auth Key will be used to authenticate with the Tailscale API and manage the sandbox's Tailscale node.", 8 + "input": { 9 + "encoding": "application/json", 10 + "schema": { 11 + "type": "object", 12 + "required": [ 13 + "id", 14 + "authKey" 15 + ], 16 + "properties": { 17 + "id": { 18 + "type": "string", 19 + "description": "The sandbox ID." 20 + }, 21 + "authKey": { 22 + "type": "string", 23 + "description": "The Tailscale Auth Key (encrypted) to store for the sandbox." 24 + }, 25 + "redacted": { 26 + "type": "string", 27 + "description": "The redacted SSH key." 28 + } 29 + } 30 + } 31 + }, 32 + "output": { 33 + "encoding": "application/json", 34 + "schema": { 35 + "type": "ref", 36 + "ref": "io.pocketenv.sandbox.defs#tailscaleAuthKeyView" 37 + } 38 + } 39 + } 40 + } 41 + }
+4
apps/api/lexicons/secret/addSecret.json
··· 15 15 "secret": { 16 16 "type": "ref", 17 17 "ref": "io.pocketenv.secret.defs#secret" 18 + }, 19 + "redacted": { 20 + "type": "string", 21 + "description": "The redacted secret value." 18 22 } 19 23 } 20 24 }
+25 -20
apps/api/pkl/defs/sandbox/defs.pkl
··· 203 203 } 204 204 ["repo"] = new StringType { 205 205 type = "string" 206 - description = 207 - "A git repository URL to clone into the sandbox, e.g. a GitHub/Tangled repo." 206 + description = "A git repository URL to clone into the sandbox, e.g. a GitHub/Tangled repo." 208 207 format = "uri" 209 208 } 210 209 ["vcpus"] = new IntegerType { ··· 239 238 } 240 239 ["value"] = new StringType { 241 240 type = "string" 242 - description = "The value of the secret. This will be encrypted at rest and redacted in any API responses." 241 + description = 242 + "The value of the secret. This will be encrypted at rest and redacted in any API responses." 243 243 } 244 244 } 245 245 } ··· 253 253 } 254 254 ["value"] = new StringType { 255 255 type = "string" 256 - description = "The value of the variable. This will be visible in API responses and should not contain sensitive information." 256 + description = 257 + "The value of the variable. This will be visible in API responses and should not contain sensitive information." 257 258 } 258 259 } 259 260 description = "A variable to add to the sandbox" ··· 296 297 description = 297 298 "The mount path within the sandbox where the volume will be attached, e.g. '/data', '/logs', etc." 298 299 } 299 - ["readOnly"] = new BooleanType { 300 + ["readOnly"] = new BooleanType { 300 301 type = "boolean" 301 302 description = "Whether the volume should be mounted as read-only" 302 - } 303 + } 303 304 } 304 305 description = "A volume to add to the sandbox" 305 306 } ··· 307 308 type = "array" 308 309 items = new Union { 309 310 type = "union" 310 - refs = List( 311 - "#sandboxDetailsPref", 312 - "#secretPref", 313 - "#variablePref", 314 - "#filePref", 315 - "#volumePref" 316 - ) 311 + refs = 312 + List( 313 + "#sandboxDetailsPref", 314 + "#secretPref", 315 + "#variablePref", 316 + "#filePref", 317 + "#volumePref", 318 + ) 317 319 } 318 320 } 319 321 ["sshKeysView"] = new ObjectType { ··· 343 345 } 344 346 } 345 347 } 346 - ["tailscaleTokenView"] = new ObjectType { 348 + ["tailscaleAuthKeyView"] = new ObjectType { 347 349 type = "object" 348 350 properties { 349 351 ["id"] = new StringType { 350 352 type = "string" 351 - description = "Unique identifier of the Tailscale token." 353 + description = "Unique identifier of the Tailscale Auth Key." 352 354 } 353 - ["token"] = new StringType { 355 + ["authKey"] = new StringType { 354 356 type = "string" 355 - description = "The Tailscale auth token (redacted in API responses)" 357 + description = "The Tailscale auth key (redacted in API responses)" 358 + } 359 + ["redacted"] = new StringType { 360 + type = "string" 361 + description = "The redacted Auth Key." 356 362 } 357 363 ["createdAt"] = new StringType { 358 364 type = "string" 359 - description = "The timestamp when the Tailscale token was created." 365 + description = "The timestamp when the Tailscale Auth Key was created." 360 366 format = "datetime" 361 367 } 362 368 ["updatedAt"] = new StringType { 363 369 type = "string" 364 - description = "The timestamp when the Tailscale token was last updated." 370 + description = "The timestamp when the Tailscale Auth Key was last updated." 365 371 format = "datetime" 366 372 } 367 373 } ··· 403 409 } 404 410 } 405 411 } 406 -
+3 -3
apps/api/pkl/defs/sandbox/getTailscaleToken.pkl apps/api/pkl/defs/sandbox/getTailscaleAuthKey.pkl
··· 1 1 amends "../../schema/lexicon.pkl" 2 2 3 3 lexicon = 1 4 - id = "io.pocketenv.sandbox.getTailscaleToken" 4 + id = "io.pocketenv.sandbox.getTailscaleAuthKey" 5 5 defs = new Mapping<String, Query> { 6 6 ["main"] { 7 7 type = "query" ··· 20 20 encoding = "application/json" 21 21 schema = new Ref { 22 22 type = "ref" 23 - ref = "io.pocketenv.sandbox.defs#tailscaleTokenView" 23 + ref = "io.pocketenv.sandbox.defs#tailscaleAuthKeyView" 24 24 } 25 25 } 26 26 } 27 - } 27 + }
+17 -13
apps/api/pkl/defs/sandbox/putSshKeys.pkl
··· 12 12 type = "object" 13 13 required = List("id", "privateKey", "publicKey") 14 14 properties { 15 - ["id"] = new StringType { 16 - type = "string" 17 - description = "The sandbox ID." 18 - } 19 - ["privateKey"] = new StringType { 20 - type = "string" 21 - description = "The private SSH key (encrypted)" 22 - } 23 - ["publicKey"] = new StringType { 24 - type = "string" 25 - description = "The public SSH key." 15 + ["id"] = new StringType { 16 + type = "string" 17 + description = "The sandbox ID." 18 + } 19 + ["privateKey"] = new StringType { 20 + type = "string" 21 + description = "The private SSH key (encrypted)" 22 + } 23 + ["publicKey"] = new StringType { 24 + type = "string" 25 + description = "The public SSH key." 26 + } 27 + ["redacted"] = new StringType { 28 + type = "string" 29 + description = "The redacted SSH key." 30 + } 26 31 } 27 32 } 28 33 } 29 - } 30 34 output { 31 35 encoding = "application/json" 32 36 schema = new Ref { ··· 35 39 } 36 40 } 37 41 } 38 - } 42 + }
+39
apps/api/pkl/defs/sandbox/putTailscaleAuthKey.pkl
··· 1 + amends "../../schema/lexicon.pkl" 2 + 3 + lexicon = 1 4 + id = "io.pocketenv.sandbox.putTailscaleAuthKey" 5 + defs = new Mapping<String, Procedure> { 6 + ["main"] { 7 + type = "procedure" 8 + description = 9 + "Store a Tailscale Auth Key for the sandbox. This Auth Key will be used to authenticate with the Tailscale API and manage the sandbox's Tailscale node." 10 + input { 11 + encoding = "application/json" 12 + schema = new ObjectType { 13 + type = "object" 14 + required = List("id", "authKey") 15 + properties { 16 + ["id"] = new StringType { 17 + type = "string" 18 + description = "The sandbox ID." 19 + } 20 + ["authKey"] = new StringType { 21 + type = "string" 22 + description = "The Tailscale Auth Key (encrypted) to store for the sandbox." 23 + } 24 + ["redacted"] = new StringType { 25 + type = "string" 26 + description = "The redacted SSH key." 27 + } 28 + } 29 + } 30 + } 31 + output { 32 + encoding = "application/json" 33 + schema = new Ref { 34 + type = "ref" 35 + ref = "io.pocketenv.sandbox.defs#tailscaleAuthKeyView" 36 + } 37 + } 38 + } 39 + }
-34
apps/api/pkl/defs/sandbox/putTailscaleToken.pkl
··· 1 - amends "../../schema/lexicon.pkl" 2 - 3 - lexicon = 1 4 - id = "io.pocketenv.sandbox.putTailscaleToken" 5 - defs = new Mapping<String, Procedure> { 6 - ["main"] { 7 - type = "procedure" 8 - description = "Store a Tailscale token for the sandbox. This token will be used to authenticate with the Tailscale API and manage the sandbox's Tailscale node." 9 - input { 10 - encoding = "application/json" 11 - schema = new ObjectType { 12 - type = "object" 13 - required = List("id", "token") 14 - properties { 15 - ["id"] = new StringType { 16 - type = "string" 17 - description = "The sandbox ID." 18 - } 19 - ["token"] = new StringType { 20 - type = "string" 21 - description = "The Tailscale token (encrypted) to store for the sandbox." 22 - } 23 - } 24 - } 25 - } 26 - output { 27 - encoding = "application/json" 28 - schema = new Ref { 29 - type = "ref" 30 - ref = "io.pocketenv.sandbox.defs#tailscaleTokenView" 31 - } 32 - } 33 - } 34 - }
+5 -1
apps/api/pkl/defs/secret/addSecret.pkl
··· 15 15 type = "ref" 16 16 ref = "io.pocketenv.secret.defs#secret" 17 17 } 18 + ["redacted"] = new StringType { 19 + type = "string" 20 + description = "The redacted secret value." 21 + } 18 22 } 19 23 } 20 24 } 21 25 } 22 - } 26 + }
+24
apps/api/src/lexicon/index.ts
··· 24 24 import type * as IoPocketenvSandboxGetSandbox from "./types/io/pocketenv/sandbox/getSandbox"; 25 25 import type * as IoPocketenvSandboxGetSandboxes from "./types/io/pocketenv/sandbox/getSandboxes"; 26 26 import type * as IoPocketenvSandboxGetSshKeys from "./types/io/pocketenv/sandbox/getSshKeys"; 27 + import type * as IoPocketenvSandboxGetTailscaleAuthKey from "./types/io/pocketenv/sandbox/getTailscaleAuthKey"; 27 28 import type * as IoPocketenvSandboxGetTailscaleToken from "./types/io/pocketenv/sandbox/getTailscaleToken"; 28 29 import type * as IoPocketenvSandboxPutPreferences from "./types/io/pocketenv/sandbox/putPreferences"; 29 30 import type * as IoPocketenvSandboxPutSshKeys from "./types/io/pocketenv/sandbox/putSshKeys"; 31 + import type * as IoPocketenvSandboxPutTailscaleAuthKey from "./types/io/pocketenv/sandbox/putTailscaleAuthKey"; 30 32 import type * as IoPocketenvSandboxPutTailscaleToken from "./types/io/pocketenv/sandbox/putTailscaleToken"; 31 33 import type * as IoPocketenvSandboxStartSandbox from "./types/io/pocketenv/sandbox/startSandbox"; 32 34 import type * as IoPocketenvSandboxStopSandbox from "./types/io/pocketenv/sandbox/stopSandbox"; ··· 277 279 return this._server.xrpc.method(nsid, cfg); 278 280 } 279 281 282 + getTailscaleAuthKey<AV extends AuthVerifier>( 283 + cfg: ConfigOf< 284 + AV, 285 + IoPocketenvSandboxGetTailscaleAuthKey.Handler<ExtractAuth<AV>>, 286 + IoPocketenvSandboxGetTailscaleAuthKey.HandlerReqCtx<ExtractAuth<AV>> 287 + >, 288 + ) { 289 + const nsid = "io.pocketenv.sandbox.getTailscaleAuthKey"; // @ts-ignore 290 + return this._server.xrpc.method(nsid, cfg); 291 + } 292 + 280 293 getTailscaleToken<AV extends AuthVerifier>( 281 294 cfg: ConfigOf< 282 295 AV, ··· 307 320 >, 308 321 ) { 309 322 const nsid = "io.pocketenv.sandbox.putSshKeys"; // @ts-ignore 323 + return this._server.xrpc.method(nsid, cfg); 324 + } 325 + 326 + putTailscaleAuthKey<AV extends AuthVerifier>( 327 + cfg: ConfigOf< 328 + AV, 329 + IoPocketenvSandboxPutTailscaleAuthKey.Handler<ExtractAuth<AV>>, 330 + IoPocketenvSandboxPutTailscaleAuthKey.HandlerReqCtx<ExtractAuth<AV>> 331 + >, 332 + ) { 333 + const nsid = "io.pocketenv.sandbox.putTailscaleAuthKey"; // @ts-ignore 310 334 return this._server.xrpc.method(nsid, cfg); 311 335 } 312 336
+90 -6
apps/api/src/lexicon/lexicons.ts
··· 868 868 }, 869 869 }, 870 870 }, 871 - tailscaleTokenView: { 871 + tailscaleAuthKeyView: { 872 872 type: "object", 873 873 properties: { 874 874 id: { 875 875 type: "string", 876 - description: "Unique identifier of the Tailscale token.", 876 + description: "Unique identifier of the Tailscale Auth Key.", 877 + }, 878 + authKey: { 879 + type: "string", 880 + description: "The Tailscale auth key (redacted in API responses)", 877 881 }, 878 - token: { 882 + redacted: { 879 883 type: "string", 880 - description: "The Tailscale auth token (redacted in API responses)", 884 + description: "The redacted Auth Key.", 881 885 }, 882 886 createdAt: { 883 887 type: "string", 884 - description: "The timestamp when the Tailscale token was created.", 888 + description: 889 + "The timestamp when the Tailscale Auth Key was created.", 885 890 format: "datetime", 886 891 }, 887 892 updatedAt: { 888 893 type: "string", 889 894 description: 890 - "The timestamp when the Tailscale token was last updated.", 895 + "The timestamp when the Tailscale Auth Key was last updated.", 891 896 format: "datetime", 892 897 }, 893 898 }, ··· 1112 1117 }, 1113 1118 }, 1114 1119 }, 1120 + IoPocketenvSandboxGetTailscaleAuthKey: { 1121 + lexicon: 1, 1122 + id: "io.pocketenv.sandbox.getTailscaleAuthKey", 1123 + defs: { 1124 + main: { 1125 + type: "query", 1126 + description: "Get the Tailscale token for a sandbox.", 1127 + parameters: { 1128 + type: "params", 1129 + required: ["id"], 1130 + properties: { 1131 + id: { 1132 + type: "string", 1133 + description: "The sandbox ID.", 1134 + }, 1135 + }, 1136 + }, 1137 + output: { 1138 + encoding: "application/json", 1139 + schema: { 1140 + type: "ref", 1141 + ref: "lex:io.pocketenv.sandbox.defs#tailscaleAuthKeyView", 1142 + }, 1143 + }, 1144 + }, 1145 + }, 1146 + }, 1115 1147 IoPocketenvSandboxGetTailscaleToken: { 1116 1148 lexicon: 1, 1117 1149 id: "io.pocketenv.sandbox.getTailscaleToken", ··· 1186 1218 publicKey: { 1187 1219 type: "string", 1188 1220 description: "The public SSH key.", 1221 + }, 1222 + redacted: { 1223 + type: "string", 1224 + description: "The redacted SSH key.", 1189 1225 }, 1190 1226 }, 1191 1227 }, ··· 1200 1236 }, 1201 1237 }, 1202 1238 }, 1239 + IoPocketenvSandboxPutTailscaleAuthKey: { 1240 + lexicon: 1, 1241 + id: "io.pocketenv.sandbox.putTailscaleAuthKey", 1242 + defs: { 1243 + main: { 1244 + type: "procedure", 1245 + description: 1246 + "Store a Tailscale Auth Key for the sandbox. This Auth Key will be used to authenticate with the Tailscale API and manage the sandbox's Tailscale node.", 1247 + input: { 1248 + encoding: "application/json", 1249 + schema: { 1250 + type: "object", 1251 + required: ["id", "authKey"], 1252 + properties: { 1253 + id: { 1254 + type: "string", 1255 + description: "The sandbox ID.", 1256 + }, 1257 + authKey: { 1258 + type: "string", 1259 + description: 1260 + "The Tailscale Auth Key (encrypted) to store for the sandbox.", 1261 + }, 1262 + redacted: { 1263 + type: "string", 1264 + description: "The redacted SSH key.", 1265 + }, 1266 + }, 1267 + }, 1268 + }, 1269 + output: { 1270 + encoding: "application/json", 1271 + schema: { 1272 + type: "ref", 1273 + ref: "lex:io.pocketenv.sandbox.defs#tailscaleAuthKeyView", 1274 + }, 1275 + }, 1276 + }, 1277 + }, 1278 + }, 1203 1279 IoPocketenvSandboxPutTailscaleToken: { 1204 1280 lexicon: 1, 1205 1281 id: "io.pocketenv.sandbox.putTailscaleToken", ··· 1515 1591 secret: { 1516 1592 type: "ref", 1517 1593 ref: "lex:io.pocketenv.secret.defs#secret", 1594 + }, 1595 + redacted: { 1596 + type: "string", 1597 + description: "The redacted secret value.", 1518 1598 }, 1519 1599 }, 1520 1600 }, ··· 2023 2103 IoPocketenvSandboxGetSandbox: "io.pocketenv.sandbox.getSandbox", 2024 2104 IoPocketenvSandboxGetSandboxes: "io.pocketenv.sandbox.getSandboxes", 2025 2105 IoPocketenvSandboxGetSshKeys: "io.pocketenv.sandbox.getSshKeys", 2106 + IoPocketenvSandboxGetTailscaleAuthKey: 2107 + "io.pocketenv.sandbox.getTailscaleAuthKey", 2026 2108 IoPocketenvSandboxGetTailscaleToken: "io.pocketenv.sandbox.getTailscaleToken", 2027 2109 IoPocketenvSandboxPutPreferences: "io.pocketenv.sandbox.putPreferences", 2028 2110 IoPocketenvSandboxPutSshKeys: "io.pocketenv.sandbox.putSshKeys", 2111 + IoPocketenvSandboxPutTailscaleAuthKey: 2112 + "io.pocketenv.sandbox.putTailscaleAuthKey", 2029 2113 IoPocketenvSandboxPutTailscaleToken: "io.pocketenv.sandbox.putTailscaleToken", 2030 2114 IoPocketenvSandbox: "io.pocketenv.sandbox", 2031 2115 IoPocketenvSandboxStartSandbox: "io.pocketenv.sandbox.startSandbox",
+12 -10
apps/api/src/lexicon/types/io/pocketenv/sandbox/defs.ts
··· 251 251 return lexicons.validate("io.pocketenv.sandbox.defs#sshKeysView", v); 252 252 } 253 253 254 - export interface TailscaleTokenView { 255 - /** Unique identifier of the Tailscale token. */ 254 + export interface TailscaleAuthKeyView { 255 + /** Unique identifier of the Tailscale Auth Key. */ 256 256 id?: string; 257 - /** The Tailscale auth token (redacted in API responses) */ 258 - token?: string; 259 - /** The timestamp when the Tailscale token was created. */ 257 + /** The Tailscale auth key (redacted in API responses) */ 258 + authKey?: string; 259 + /** The redacted Auth Key. */ 260 + redacted?: string; 261 + /** The timestamp when the Tailscale Auth Key was created. */ 260 262 createdAt?: string; 261 - /** The timestamp when the Tailscale token was last updated. */ 263 + /** The timestamp when the Tailscale Auth Key was last updated. */ 262 264 updatedAt?: string; 263 265 [k: string]: unknown; 264 266 } 265 267 266 - export function isTailscaleTokenView(v: unknown): v is TailscaleTokenView { 268 + export function isTailscaleAuthKeyView(v: unknown): v is TailscaleAuthKeyView { 267 269 return ( 268 270 isObj(v) && 269 271 hasProp(v, "$type") && 270 - v.$type === "io.pocketenv.sandbox.defs#tailscaleTokenView" 272 + v.$type === "io.pocketenv.sandbox.defs#tailscaleAuthKeyView" 271 273 ); 272 274 } 273 275 274 - export function validateTailscaleTokenView(v: unknown): ValidationResult { 275 - return lexicons.validate("io.pocketenv.sandbox.defs#tailscaleTokenView", v); 276 + export function validateTailscaleAuthKeyView(v: unknown): ValidationResult { 277 + return lexicons.validate("io.pocketenv.sandbox.defs#tailscaleAuthKeyView", v); 276 278 } 277 279 278 280 export interface IntegrationView {
+43
apps/api/src/lexicon/types/io/pocketenv/sandbox/getTailscaleAuthKey.ts
··· 1 + /** 2 + * GENERATED CODE - DO NOT MODIFY 3 + */ 4 + import type express from "express"; 5 + import { ValidationResult, BlobRef } from "@atproto/lexicon"; 6 + import { lexicons } from "../../../../lexicons"; 7 + import { isObj, hasProp } from "../../../../util"; 8 + import { CID } from "multiformats/cid"; 9 + import type { HandlerAuth, HandlerPipeThrough } from "@atproto/xrpc-server"; 10 + import type * as IoPocketenvSandboxDefs from "./defs"; 11 + 12 + export interface QueryParams { 13 + /** The sandbox ID. */ 14 + id: string; 15 + } 16 + 17 + export type InputSchema = undefined; 18 + export type OutputSchema = IoPocketenvSandboxDefs.TailscaleAuthKeyView; 19 + export type HandlerInput = undefined; 20 + 21 + export interface HandlerSuccess { 22 + encoding: "application/json"; 23 + body: OutputSchema; 24 + headers?: { [key: string]: string }; 25 + } 26 + 27 + export interface HandlerError { 28 + status: number; 29 + message?: string; 30 + } 31 + 32 + export type HandlerOutput = HandlerError | HandlerSuccess | HandlerPipeThrough; 33 + export type HandlerReqCtx<HA extends HandlerAuth = never> = { 34 + auth: HA; 35 + params: QueryParams; 36 + input: HandlerInput; 37 + req: express.Request; 38 + res: express.Response; 39 + resetRouteRateLimits: () => Promise<void>; 40 + }; 41 + export type Handler<HA extends HandlerAuth = never> = ( 42 + ctx: HandlerReqCtx<HA>, 43 + ) => Promise<HandlerOutput> | HandlerOutput;
+2
apps/api/src/lexicon/types/io/pocketenv/sandbox/putSshKeys.ts
··· 18 18 privateKey: string; 19 19 /** The public SSH key. */ 20 20 publicKey: string; 21 + /** The redacted SSH key. */ 22 + redacted?: string; 21 23 [k: string]: unknown; 22 24 } 23 25
+53
apps/api/src/lexicon/types/io/pocketenv/sandbox/putTailscaleAuthKey.ts
··· 1 + /** 2 + * GENERATED CODE - DO NOT MODIFY 3 + */ 4 + import type express from "express"; 5 + import { ValidationResult, BlobRef } from "@atproto/lexicon"; 6 + import { lexicons } from "../../../../lexicons"; 7 + import { isObj, hasProp } from "../../../../util"; 8 + import { CID } from "multiformats/cid"; 9 + import type { HandlerAuth, HandlerPipeThrough } from "@atproto/xrpc-server"; 10 + import type * as IoPocketenvSandboxDefs from "./defs"; 11 + 12 + export type QueryParams = {}; 13 + 14 + export interface InputSchema { 15 + /** The sandbox ID. */ 16 + id: string; 17 + /** The Tailscale Auth Key (encrypted) to store for the sandbox. */ 18 + authKey: string; 19 + /** The redacted SSH key. */ 20 + redacted?: string; 21 + [k: string]: unknown; 22 + } 23 + 24 + export type OutputSchema = IoPocketenvSandboxDefs.TailscaleAuthKeyView; 25 + 26 + export interface HandlerInput { 27 + encoding: "application/json"; 28 + body: InputSchema; 29 + } 30 + 31 + export interface HandlerSuccess { 32 + encoding: "application/json"; 33 + body: OutputSchema; 34 + headers?: { [key: string]: string }; 35 + } 36 + 37 + export interface HandlerError { 38 + status: number; 39 + message?: string; 40 + } 41 + 42 + export type HandlerOutput = HandlerError | HandlerSuccess | HandlerPipeThrough; 43 + export type HandlerReqCtx<HA extends HandlerAuth = never> = { 44 + auth: HA; 45 + params: QueryParams; 46 + input: HandlerInput; 47 + req: express.Request; 48 + res: express.Response; 49 + resetRouteRateLimits: () => Promise<void>; 50 + }; 51 + export type Handler<HA extends HandlerAuth = never> = ( 52 + ctx: HandlerReqCtx<HA>, 53 + ) => Promise<HandlerOutput> | HandlerOutput;
+2
apps/api/src/lexicon/types/io/pocketenv/secret/addSecret.ts
··· 13 13 14 14 export interface InputSchema { 15 15 secret: IoPocketenvSecretDefs.Secret; 16 + /** The redacted secret value. */ 17 + redacted?: string; 16 18 [k: string]: unknown; 17 19 } 18 20
+4
apps/api/src/schema/index.ts
··· 9 9 import sandboxVolumes from "./sandbox-volumes"; 10 10 import files from "./files"; 11 11 import sandboxFiles from "./sandbox-files"; 12 + import tailscaleAuthKeys from "./tailscale-auth-keys"; 13 + import sshKeys from "./ssh-keys"; 12 14 13 15 export default { 14 16 sandboxes, ··· 22 24 sandboxVolumes, 23 25 files, 24 26 sandboxFiles, 27 + tailscaleAuthKeys, 28 + sshKeys, 25 29 };
+1 -3
apps/api/src/schema/sandboxes.ts
··· 9 9 import users from "./users"; 10 10 11 11 const sandboxes = pgTable("sandboxes", { 12 - id: text("id") 13 - .primaryKey() 14 - .default(sql`sandbox_id()`), 12 + id: text("id").primaryKey().default(sql`sandbox_id()`), 15 13 base: text("base"), 16 14 name: text("name").unique().notNull(), 17 15 displayName: text("display_name"),
+15 -9
apps/api/src/schema/ssh-keys.ts
··· 1 1 import { type InferInsertModel, type InferSelectModel, sql } from "drizzle-orm"; 2 - import { pgTable, text, timestamp } from "drizzle-orm/pg-core"; 2 + import { pgTable, text, timestamp, uniqueIndex } from "drizzle-orm/pg-core"; 3 3 import sandboxes from "./sandboxes"; 4 4 5 - const sshKeys = pgTable("ssh_keys", { 6 - id: text("id").primaryKey().default(sql`xata_id()`), 7 - sandboxId: text("sandbox_id").references(() => sandboxes.id), 8 - publicKey: text("public_key").notNull(), 9 - privateKey: text("private_key").notNull(), 10 - redacted: text("redacted").notNull(), 11 - createdAt: timestamp("created_at").defaultNow().notNull(), 12 - }); 5 + const sshKeys = pgTable( 6 + "ssh_keys", 7 + { 8 + id: text("id").primaryKey().default(sql`xata_id()`), 9 + sandboxId: text("sandbox_id") 10 + .notNull() 11 + .references(() => sandboxes.id), 12 + publicKey: text("public_key").notNull(), 13 + privateKey: text("private_key").notNull(), 14 + redacted: text("redacted"), 15 + createdAt: timestamp("created_at").defaultNow().notNull(), 16 + }, 17 + (t) => [uniqueIndex("unique_sandbox_ssh_key").on(t.publicKey, t.sandboxId)], 18 + ); 13 19 14 20 export type SelectSshKey = InferSelectModel<typeof sshKeys>; 15 21 export type InsertSshKey = InferInsertModel<typeof sshKeys>;
+18
apps/api/src/schema/tailscale-auth-keys.ts
··· 1 + import { type InferInsertModel, type InferSelectModel, sql } from "drizzle-orm"; 2 + import { pgTable, text, timestamp } from "drizzle-orm/pg-core"; 3 + import sandboxes from "./sandboxes"; 4 + 5 + const tailscaleAuthKey = pgTable("tailscale_auth_keys", { 6 + id: text("id").primaryKey().default(sql`xata_id()`), 7 + sandboxId: text("sandbox_id") 8 + .notNull() 9 + .references(() => sandboxes.id), 10 + authKey: text("auth_key").notNull(), 11 + redacted: text("redacted").notNull(), 12 + createdAt: timestamp("created_at").defaultNow().notNull(), 13 + }); 14 + 15 + export type SelectTailscaleAuthKey = InferSelectModel<typeof tailscaleAuthKey>; 16 + export type InsertTailscaleAuthKey = InferInsertModel<typeof tailscaleAuthKey>; 17 + 18 + export default tailscaleAuthKey;
-16
apps/api/src/schema/tailscale-tokens.ts
··· 1 - import { type InferInsertModel, type InferSelectModel, sql } from "drizzle-orm"; 2 - import { pgTable, text, timestamp } from "drizzle-orm/pg-core"; 3 - import sandboxes from "./sandboxes"; 4 - 5 - const tailscaleTokens = pgTable("tailscale_tokens", { 6 - id: text("id").primaryKey().default(sql`xata_id()`), 7 - sandboxId: text("sandbox_id").references(() => sandboxes.id), 8 - tokens: text("tokens").notNull(), 9 - redacted: text("redacted").notNull(), 10 - createdAt: timestamp("created_at").defaultNow().notNull(), 11 - }); 12 - 13 - export type SelectTailscaleToken = InferSelectModel<typeof tailscaleTokens>; 14 - export type InsertTailscaleToken = InferInsertModel<typeof tailscaleTokens>; 15 - 16 - export default tailscaleTokens;
+4 -4
apps/api/src/xrpc/index.ts
··· 26 26 import createIntegration from "./io/pocketenv/sandbox/createIntegration"; 27 27 import getIntegrations from "./io/pocketenv/sandbox/getIntegrations"; 28 28 import getSshKeys from "./io/pocketenv/sandbox/getSshKeys"; 29 - import getTailscaleToken from "./io/pocketenv/sandbox/getTailscaleToken"; 29 + import getTailscaleAuthKey from "./io/pocketenv/sandbox/getTailscaleAuthKey"; 30 30 import putSshKeys from "./io/pocketenv/sandbox/putSshKeys"; 31 - import putTailscaleToken from "./io/pocketenv/sandbox/putTailscaleToken"; 31 + import putTailscaleAuthKey from "./io/pocketenv/sandbox/putTailscaleAuthKey"; 32 32 33 33 export default function (server: Server, ctx: Context) { 34 34 // io.pocketenv ··· 58 58 createIntegration(server, ctx); 59 59 getIntegrations(server, ctx); 60 60 getSshKeys(server, ctx); 61 - getTailscaleToken(server, ctx); 61 + getTailscaleAuthKey(server, ctx); 62 62 putSshKeys(server, ctx); 63 - putTailscaleToken(server, ctx); 63 + putTailscaleAuthKey(server, ctx); 64 64 65 65 return server; 66 66 }
+27 -3
apps/api/src/xrpc/io/pocketenv/sandbox/getSshKeys.ts
··· 1 1 import { XRPCError, type HandlerAuth } from "@atproto/xrpc-server"; 2 2 import type { Context } from "context"; 3 + import { eq } from "drizzle-orm"; 3 4 import type { Server } from "lexicon"; 4 - import type { QueryParams } from "lexicon/types/io/pocketenv/sandbox/getSshKeys"; 5 + import type { 6 + QueryParams, 7 + OutputSchema, 8 + } from "lexicon/types/io/pocketenv/sandbox/getSshKeys"; 9 + import sshKeys from "schema/ssh-keys"; 5 10 6 11 export default function (server: Server, ctx: Context) { 7 12 const getSshKeys = async (params: QueryParams, auth: HandlerAuth) => { 8 - return {}; 13 + if (!auth.credentials) { 14 + throw new XRPCError(401, "Unauthorized"); 15 + } 16 + 17 + const [result] = await ctx.db 18 + .select() 19 + .from(sshKeys) 20 + .where(eq(sshKeys.sandboxId, params.id)) 21 + .execute(); 22 + 23 + if (!result) { 24 + throw new XRPCError(404, "Not found"); 25 + } 26 + return { 27 + id: result.id, 28 + privateKey: result.redacted || "", 29 + publicKey: result.publicKey, 30 + createdAt: result.createdAt.toISOString(), 31 + }; 9 32 }; 33 + 10 34 server.io.pocketenv.sandbox.getSshKeys({ 11 35 auth: ctx.authVerifier, 12 36 handler: async ({ params, auth }) => { 13 37 const result = await getSshKeys(params, auth); 14 38 return { 15 39 encoding: "application/json", 16 - body: result as any, // TODO: Implement getSshKeys 40 + body: result satisfies OutputSchema, 17 41 }; 18 42 }, 19 43 });
+43
apps/api/src/xrpc/io/pocketenv/sandbox/getTailscaleAuthKey.ts
··· 1 + import { XRPCError, type HandlerAuth } from "@atproto/xrpc-server"; 2 + import type { Context } from "context"; 3 + import { eq } from "drizzle-orm"; 4 + import type { Server } from "lexicon"; 5 + import type { QueryParams } from "lexicon/types/io/pocketenv/sandbox/getTailscaleAuthKey"; 6 + import tailscaleAuthKey from "schema/tailscale-auth-keys"; 7 + 8 + export default function (server: Server, ctx: Context) { 9 + const getTailscaleAuthKey = async ( 10 + params: QueryParams, 11 + auth: HandlerAuth, 12 + ) => { 13 + if (!auth.credentials) { 14 + throw new XRPCError(401, "Unauthorized"); 15 + } 16 + 17 + const [result] = await ctx.db 18 + .select() 19 + .from(tailscaleAuthKey) 20 + .where(eq(tailscaleAuthKey.sandboxId, params.id)) 21 + .execute(); 22 + 23 + if (!result) { 24 + throw new XRPCError(404, "Not found"); 25 + } 26 + 27 + return { 28 + id: result.id, 29 + authKey: result.redacted, 30 + createdAt: result.createdAt.toISOString(), 31 + }; 32 + }; 33 + server.io.pocketenv.sandbox.getTailscaleAuthKey({ 34 + auth: ctx.authVerifier, 35 + handler: async ({ params, auth }) => { 36 + const result = await getTailscaleAuthKey(params, auth); 37 + return { 38 + encoding: "application/json", 39 + body: result, 40 + }; 41 + }, 42 + }); 43 + }
-20
apps/api/src/xrpc/io/pocketenv/sandbox/getTailscaleToken.ts
··· 1 - import { XRPCError, type HandlerAuth } from "@atproto/xrpc-server"; 2 - import type { Context } from "context"; 3 - import type { Server } from "lexicon"; 4 - import type { QueryParams } from "lexicon/types/io/pocketenv/sandbox/getTailscaleToken"; 5 - 6 - export default function (server: Server, ctx: Context) { 7 - const getTailscaleToken = async (params: QueryParams, auth: HandlerAuth) => { 8 - return {}; 9 - }; 10 - server.io.pocketenv.sandbox.getIntegrations({ 11 - auth: ctx.authVerifier, 12 - handler: async ({ params, auth }) => { 13 - const result = await getTailscaleToken(params, auth); 14 - return { 15 - encoding: "application/json", 16 - body: result as any, // TODO: Implement getIntegrations 17 - }; 18 - }, 19 - }); 20 - }
+4
apps/api/src/xrpc/io/pocketenv/sandbox/putPreferences.ts
··· 5 5 6 6 export default function (server: Server, ctx: Context) { 7 7 const putPreferences = async (input: HandlerInput, auth: HandlerAuth) => { 8 + if (!auth.credentials) { 9 + throw new XRPCError(401, "Unauthorized"); 10 + } 11 + 8 12 return {}; 9 13 }; 10 14 server.io.pocketenv.sandbox.putPreferences({
+15
apps/api/src/xrpc/io/pocketenv/sandbox/putSshKeys.ts
··· 2 2 import type { Context } from "context"; 3 3 import type { Server } from "lexicon"; 4 4 import type { InputSchema } from "lexicon/types/io/pocketenv/sandbox/putSshKeys"; 5 + import sshKeys from "schema/ssh-keys"; 5 6 6 7 export default function (server: Server, ctx: Context) { 7 8 const putSshKeys = async (input: InputSchema, auth: HandlerAuth) => { 9 + if (!auth.credentials) { 10 + throw new XRPCError(401, "Unauthorized"); 11 + } 12 + 13 + await ctx.db 14 + .insert(sshKeys) 15 + .values({ 16 + publicKey: input.publicKey, 17 + privateKey: input.privateKey, 18 + redacted: input.redacted, 19 + sandboxId: input.id, 20 + }) 21 + .execute(); 22 + 8 23 return {}; 9 24 }; 10 25 server.io.pocketenv.sandbox.putSshKeys({
+34
apps/api/src/xrpc/io/pocketenv/sandbox/putTailscaleAuthKey.ts
··· 1 + import { XRPCError, type HandlerAuth } from "@atproto/xrpc-server"; 2 + import type { Context } from "context"; 3 + import type { Server } from "lexicon"; 4 + import type { InputSchema } from "lexicon/types/io/pocketenv/sandbox/putTailscaleAuthKey"; 5 + import tailscaleAuthKeys from "schema/tailscale-auth-keys"; 6 + 7 + export default function (server: Server, ctx: Context) { 8 + const putTailscaleAuthKey = async (input: InputSchema, auth: HandlerAuth) => { 9 + if (!auth.credentials) { 10 + throw new XRPCError(401, "Unauthorized"); 11 + } 12 + 13 + await ctx.db 14 + .insert(tailscaleAuthKeys) 15 + .values({ 16 + sandboxId: input.id, 17 + authKey: input.authKey, 18 + redacted: input.redacted || "", 19 + }) 20 + .execute(); 21 + 22 + return {}; 23 + }; 24 + server.io.pocketenv.sandbox.putTailscaleAuthKey({ 25 + auth: ctx.authVerifier, 26 + handler: async ({ input, auth }) => { 27 + const result = await putTailscaleAuthKey(input.body, auth); 28 + return { 29 + encoding: "application/json", 30 + body: result as any, // TODO: Implement createIntegration 31 + }; 32 + }, 33 + }); 34 + }
-20
apps/api/src/xrpc/io/pocketenv/sandbox/putTailscaleToken.ts
··· 1 - import { XRPCError, type HandlerAuth } from "@atproto/xrpc-server"; 2 - import type { Context } from "context"; 3 - import type { Server } from "lexicon"; 4 - import type { InputSchema } from "lexicon/types/io/pocketenv/sandbox/putTailscaleToken"; 5 - 6 - export default function (server: Server, ctx: Context) { 7 - const putTailscaleToken = async (input: InputSchema, auth: HandlerAuth) => { 8 - return {}; 9 - }; 10 - server.io.pocketenv.sandbox.putTailscaleToken({ 11 - auth: ctx.authVerifier, 12 - handler: async ({ input, auth }) => { 13 - const result = await putTailscaleToken(input.body, auth); 14 - return { 15 - encoding: "application/json", 16 - body: result as any, // TODO: Implement createIntegration 17 - }; 18 - }, 19 - }); 20 - }
+1
apps/api/src/xrpc/io/pocketenv/secret/addSecret.ts
··· 17 17 .values({ 18 18 name: input.body.secret.name, 19 19 value: input.body.secret.value, 20 + redacted: input.body.redacted, 20 21 }) 21 22 .returning() 22 23 .execute();
+1
apps/cf-sandbox/drizzle/0022_dry_mojo.sql
··· 1 + ALTER TABLE "ssh_keys" ALTER COLUMN "sandbox_id" SET NOT NULL;
+1
apps/cf-sandbox/drizzle/0023_brown_mulholland_black.sql
··· 1 + ALTER TABLE "ssh_keys" ALTER COLUMN "redacted" DROP NOT NULL;
+1
apps/cf-sandbox/drizzle/0024_nasty_miek.sql
··· 1 + CREATE UNIQUE INDEX "unique_sandbox_ssh_key" ON "ssh_keys" USING btree ("public_key","sandbox_id");
+10
apps/cf-sandbox/drizzle/0025_worthless_old_lace.sql
··· 1 + CREATE TABLE "tailscale_auth_keys" ( 2 + "id" text PRIMARY KEY DEFAULT xata_id() NOT NULL, 3 + "sandbox_id" text NOT NULL, 4 + "auth_key" text NOT NULL, 5 + "redacted" text NOT NULL, 6 + "created_at" timestamp DEFAULT now() NOT NULL 7 + ); 8 + --> statement-breakpoint 9 + DROP TABLE "tailscale_tokens" CASCADE;--> statement-breakpoint 10 + ALTER TABLE "tailscale_auth_keys" ADD CONSTRAINT "tailscale_auth_keys_sandbox_id_sandboxes_id_fk" FOREIGN KEY ("sandbox_id") REFERENCES "public"."sandboxes"("id") ON DELETE no action ON UPDATE no action;
+1293
apps/cf-sandbox/drizzle/meta/0022_snapshot.json
··· 1 + { 2 + "id": "3bfd8c5c-cb46-4e30-bce1-4ea9bae3935f", 3 + "prevId": "f478e38d-5ee2-4bb8-bb1f-5fc2b01fce75", 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": "variable_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": "xata_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": { 146 + "name": "unique_sandbox_file", 147 + "columns": [ 148 + { 149 + "expression": "sandbox_id", 150 + "isExpression": false, 151 + "asc": true, 152 + "nulls": "last" 153 + }, 154 + { 155 + "expression": "file_id", 156 + "isExpression": false, 157 + "asc": true, 158 + "nulls": "last" 159 + } 160 + ], 161 + "isUnique": true, 162 + "concurrently": false, 163 + "method": "btree", 164 + "with": {} 165 + }, 166 + "unique_sandbox_file_path": { 167 + "name": "unique_sandbox_file_path", 168 + "columns": [ 169 + { 170 + "expression": "sandbox_id", 171 + "isExpression": false, 172 + "asc": true, 173 + "nulls": "last" 174 + }, 175 + { 176 + "expression": "path", 177 + "isExpression": false, 178 + "asc": true, 179 + "nulls": "last" 180 + } 181 + ], 182 + "isUnique": true, 183 + "concurrently": false, 184 + "method": "btree", 185 + "with": {} 186 + } 187 + }, 188 + "foreignKeys": { 189 + "sandbox_files_sandbox_id_sandboxes_id_fk": { 190 + "name": "sandbox_files_sandbox_id_sandboxes_id_fk", 191 + "tableFrom": "sandbox_files", 192 + "tableTo": "sandboxes", 193 + "columnsFrom": [ 194 + "sandbox_id" 195 + ], 196 + "columnsTo": [ 197 + "id" 198 + ], 199 + "onDelete": "no action", 200 + "onUpdate": "no action" 201 + }, 202 + "sandbox_files_file_id_files_id_fk": { 203 + "name": "sandbox_files_file_id_files_id_fk", 204 + "tableFrom": "sandbox_files", 205 + "tableTo": "files", 206 + "columnsFrom": [ 207 + "file_id" 208 + ], 209 + "columnsTo": [ 210 + "id" 211 + ], 212 + "onDelete": "no action", 213 + "onUpdate": "no action" 214 + } 215 + }, 216 + "compositePrimaryKeys": {}, 217 + "uniqueConstraints": {}, 218 + "policies": {}, 219 + "checkConstraints": {}, 220 + "isRLSEnabled": false 221 + }, 222 + "public.sandbox_secrets": { 223 + "name": "sandbox_secrets", 224 + "schema": "", 225 + "columns": { 226 + "id": { 227 + "name": "id", 228 + "type": "text", 229 + "primaryKey": true, 230 + "notNull": true, 231 + "default": "xata_id()" 232 + }, 233 + "sandbox_id": { 234 + "name": "sandbox_id", 235 + "type": "text", 236 + "primaryKey": false, 237 + "notNull": true 238 + }, 239 + "secret_id": { 240 + "name": "secret_id", 241 + "type": "text", 242 + "primaryKey": false, 243 + "notNull": true 244 + }, 245 + "name": { 246 + "name": "name", 247 + "type": "text", 248 + "primaryKey": false, 249 + "notNull": false 250 + }, 251 + "created_at": { 252 + "name": "created_at", 253 + "type": "timestamp", 254 + "primaryKey": false, 255 + "notNull": true, 256 + "default": "now()" 257 + }, 258 + "updated_at": { 259 + "name": "updated_at", 260 + "type": "timestamp", 261 + "primaryKey": false, 262 + "notNull": true, 263 + "default": "now()" 264 + } 265 + }, 266 + "indexes": { 267 + "unique_sandbox_secret": { 268 + "name": "unique_sandbox_secret", 269 + "columns": [ 270 + { 271 + "expression": "sandbox_id", 272 + "isExpression": false, 273 + "asc": true, 274 + "nulls": "last" 275 + }, 276 + { 277 + "expression": "secret_id", 278 + "isExpression": false, 279 + "asc": true, 280 + "nulls": "last" 281 + } 282 + ], 283 + "isUnique": true, 284 + "concurrently": false, 285 + "method": "btree", 286 + "with": {} 287 + }, 288 + "unique_sandbox_secret_by_name": { 289 + "name": "unique_sandbox_secret_by_name", 290 + "columns": [ 291 + { 292 + "expression": "sandbox_id", 293 + "isExpression": false, 294 + "asc": true, 295 + "nulls": "last" 296 + }, 297 + { 298 + "expression": "name", 299 + "isExpression": false, 300 + "asc": true, 301 + "nulls": "last" 302 + } 303 + ], 304 + "isUnique": true, 305 + "concurrently": false, 306 + "method": "btree", 307 + "with": {} 308 + } 309 + }, 310 + "foreignKeys": { 311 + "sandbox_secrets_sandbox_id_sandboxes_id_fk": { 312 + "name": "sandbox_secrets_sandbox_id_sandboxes_id_fk", 313 + "tableFrom": "sandbox_secrets", 314 + "tableTo": "sandboxes", 315 + "columnsFrom": [ 316 + "sandbox_id" 317 + ], 318 + "columnsTo": [ 319 + "id" 320 + ], 321 + "onDelete": "no action", 322 + "onUpdate": "no action" 323 + }, 324 + "sandbox_secrets_secret_id_secrets_id_fk": { 325 + "name": "sandbox_secrets_secret_id_secrets_id_fk", 326 + "tableFrom": "sandbox_secrets", 327 + "tableTo": "secrets", 328 + "columnsFrom": [ 329 + "secret_id" 330 + ], 331 + "columnsTo": [ 332 + "id" 333 + ], 334 + "onDelete": "no action", 335 + "onUpdate": "no action" 336 + } 337 + }, 338 + "compositePrimaryKeys": {}, 339 + "uniqueConstraints": {}, 340 + "policies": {}, 341 + "checkConstraints": {}, 342 + "isRLSEnabled": false 343 + }, 344 + "public.sandbox_variables": { 345 + "name": "sandbox_variables", 346 + "schema": "", 347 + "columns": { 348 + "id": { 349 + "name": "id", 350 + "type": "text", 351 + "primaryKey": true, 352 + "notNull": true, 353 + "default": "xata_id()" 354 + }, 355 + "sandbox_id": { 356 + "name": "sandbox_id", 357 + "type": "text", 358 + "primaryKey": false, 359 + "notNull": true 360 + }, 361 + "variable_id": { 362 + "name": "variable_id", 363 + "type": "text", 364 + "primaryKey": false, 365 + "notNull": true 366 + }, 367 + "name": { 368 + "name": "name", 369 + "type": "text", 370 + "primaryKey": false, 371 + "notNull": true 372 + }, 373 + "created_at": { 374 + "name": "created_at", 375 + "type": "timestamp", 376 + "primaryKey": false, 377 + "notNull": true, 378 + "default": "now()" 379 + }, 380 + "updated_at": { 381 + "name": "updated_at", 382 + "type": "timestamp", 383 + "primaryKey": false, 384 + "notNull": true, 385 + "default": "now()" 386 + } 387 + }, 388 + "indexes": { 389 + "unique_sandbox_variables": { 390 + "name": "unique_sandbox_variables", 391 + "columns": [ 392 + { 393 + "expression": "sandbox_id", 394 + "isExpression": false, 395 + "asc": true, 396 + "nulls": "last" 397 + }, 398 + { 399 + "expression": "variable_id", 400 + "isExpression": false, 401 + "asc": true, 402 + "nulls": "last" 403 + } 404 + ], 405 + "isUnique": true, 406 + "concurrently": false, 407 + "method": "btree", 408 + "with": {} 409 + }, 410 + "unique_sandbox_variables_by_name": { 411 + "name": "unique_sandbox_variables_by_name", 412 + "columns": [ 413 + { 414 + "expression": "sandbox_id", 415 + "isExpression": false, 416 + "asc": true, 417 + "nulls": "last" 418 + }, 419 + { 420 + "expression": "name", 421 + "isExpression": false, 422 + "asc": true, 423 + "nulls": "last" 424 + } 425 + ], 426 + "isUnique": true, 427 + "concurrently": false, 428 + "method": "btree", 429 + "with": {} 430 + } 431 + }, 432 + "foreignKeys": { 433 + "sandbox_variables_sandbox_id_sandboxes_id_fk": { 434 + "name": "sandbox_variables_sandbox_id_sandboxes_id_fk", 435 + "tableFrom": "sandbox_variables", 436 + "tableTo": "sandboxes", 437 + "columnsFrom": [ 438 + "sandbox_id" 439 + ], 440 + "columnsTo": [ 441 + "id" 442 + ], 443 + "onDelete": "no action", 444 + "onUpdate": "no action" 445 + }, 446 + "sandbox_variables_variable_id_variables_id_fk": { 447 + "name": "sandbox_variables_variable_id_variables_id_fk", 448 + "tableFrom": "sandbox_variables", 449 + "tableTo": "variables", 450 + "columnsFrom": [ 451 + "variable_id" 452 + ], 453 + "columnsTo": [ 454 + "id" 455 + ], 456 + "onDelete": "no action", 457 + "onUpdate": "no action" 458 + } 459 + }, 460 + "compositePrimaryKeys": {}, 461 + "uniqueConstraints": {}, 462 + "policies": {}, 463 + "checkConstraints": {}, 464 + "isRLSEnabled": false 465 + }, 466 + "public.sandbox_volumes": { 467 + "name": "sandbox_volumes", 468 + "schema": "", 469 + "columns": { 470 + "id": { 471 + "name": "id", 472 + "type": "text", 473 + "primaryKey": true, 474 + "notNull": true, 475 + "default": "xata_id()" 476 + }, 477 + "sandbox_id": { 478 + "name": "sandbox_id", 479 + "type": "text", 480 + "primaryKey": false, 481 + "notNull": true 482 + }, 483 + "volume_id": { 484 + "name": "volume_id", 485 + "type": "text", 486 + "primaryKey": false, 487 + "notNull": true 488 + }, 489 + "name": { 490 + "name": "name", 491 + "type": "text", 492 + "primaryKey": false, 493 + "notNull": false 494 + }, 495 + "path": { 496 + "name": "path", 497 + "type": "text", 498 + "primaryKey": false, 499 + "notNull": true 500 + }, 501 + "created_at": { 502 + "name": "created_at", 503 + "type": "timestamp", 504 + "primaryKey": false, 505 + "notNull": true, 506 + "default": "now()" 507 + }, 508 + "updated_at": { 509 + "name": "updated_at", 510 + "type": "timestamp", 511 + "primaryKey": false, 512 + "notNull": true, 513 + "default": "now()" 514 + } 515 + }, 516 + "indexes": { 517 + "unique_sandbox_volume": { 518 + "name": "unique_sandbox_volume", 519 + "columns": [ 520 + { 521 + "expression": "sandbox_id", 522 + "isExpression": false, 523 + "asc": true, 524 + "nulls": "last" 525 + }, 526 + { 527 + "expression": "volume_id", 528 + "isExpression": false, 529 + "asc": true, 530 + "nulls": "last" 531 + } 532 + ], 533 + "isUnique": true, 534 + "concurrently": false, 535 + "method": "btree", 536 + "with": {} 537 + }, 538 + "unique_sandbox_volume_path": { 539 + "name": "unique_sandbox_volume_path", 540 + "columns": [ 541 + { 542 + "expression": "sandbox_id", 543 + "isExpression": false, 544 + "asc": true, 545 + "nulls": "last" 546 + }, 547 + { 548 + "expression": "path", 549 + "isExpression": false, 550 + "asc": true, 551 + "nulls": "last" 552 + } 553 + ], 554 + "isUnique": true, 555 + "concurrently": false, 556 + "method": "btree", 557 + "with": {} 558 + } 559 + }, 560 + "foreignKeys": { 561 + "sandbox_volumes_sandbox_id_sandboxes_id_fk": { 562 + "name": "sandbox_volumes_sandbox_id_sandboxes_id_fk", 563 + "tableFrom": "sandbox_volumes", 564 + "tableTo": "sandboxes", 565 + "columnsFrom": [ 566 + "sandbox_id" 567 + ], 568 + "columnsTo": [ 569 + "id" 570 + ], 571 + "onDelete": "no action", 572 + "onUpdate": "no action" 573 + }, 574 + "sandbox_volumes_volume_id_volumes_id_fk": { 575 + "name": "sandbox_volumes_volume_id_volumes_id_fk", 576 + "tableFrom": "sandbox_volumes", 577 + "tableTo": "volumes", 578 + "columnsFrom": [ 579 + "volume_id" 580 + ], 581 + "columnsTo": [ 582 + "id" 583 + ], 584 + "onDelete": "no action", 585 + "onUpdate": "no action" 586 + } 587 + }, 588 + "compositePrimaryKeys": {}, 589 + "uniqueConstraints": {}, 590 + "policies": {}, 591 + "checkConstraints": {}, 592 + "isRLSEnabled": false 593 + }, 594 + "public.sandboxes": { 595 + "name": "sandboxes", 596 + "schema": "", 597 + "columns": { 598 + "id": { 599 + "name": "id", 600 + "type": "text", 601 + "primaryKey": true, 602 + "notNull": true, 603 + "default": "sandbox_id()" 604 + }, 605 + "base": { 606 + "name": "base", 607 + "type": "text", 608 + "primaryKey": false, 609 + "notNull": false 610 + }, 611 + "name": { 612 + "name": "name", 613 + "type": "text", 614 + "primaryKey": false, 615 + "notNull": true 616 + }, 617 + "display_name": { 618 + "name": "display_name", 619 + "type": "text", 620 + "primaryKey": false, 621 + "notNull": false 622 + }, 623 + "uri": { 624 + "name": "uri", 625 + "type": "text", 626 + "primaryKey": false, 627 + "notNull": false 628 + }, 629 + "cid": { 630 + "name": "cid", 631 + "type": "text", 632 + "primaryKey": false, 633 + "notNull": false 634 + }, 635 + "repo": { 636 + "name": "repo", 637 + "type": "text", 638 + "primaryKey": false, 639 + "notNull": false 640 + }, 641 + "provider": { 642 + "name": "provider", 643 + "type": "text", 644 + "primaryKey": false, 645 + "notNull": true, 646 + "default": "'cloudflare'" 647 + }, 648 + "description": { 649 + "name": "description", 650 + "type": "text", 651 + "primaryKey": false, 652 + "notNull": false 653 + }, 654 + "topics": { 655 + "name": "topics", 656 + "type": "text[]", 657 + "primaryKey": false, 658 + "notNull": false 659 + }, 660 + "logo": { 661 + "name": "logo", 662 + "type": "text", 663 + "primaryKey": false, 664 + "notNull": false 665 + }, 666 + "readme": { 667 + "name": "readme", 668 + "type": "text", 669 + "primaryKey": false, 670 + "notNull": false 671 + }, 672 + "public_key": { 673 + "name": "public_key", 674 + "type": "text", 675 + "primaryKey": false, 676 + "notNull": true 677 + }, 678 + "user_id": { 679 + "name": "user_id", 680 + "type": "text", 681 + "primaryKey": false, 682 + "notNull": false 683 + }, 684 + "instance_type": { 685 + "name": "instance_type", 686 + "type": "text", 687 + "primaryKey": false, 688 + "notNull": false 689 + }, 690 + "vcpus": { 691 + "name": "vcpus", 692 + "type": "integer", 693 + "primaryKey": false, 694 + "notNull": false 695 + }, 696 + "memory": { 697 + "name": "memory", 698 + "type": "integer", 699 + "primaryKey": false, 700 + "notNull": false 701 + }, 702 + "disk": { 703 + "name": "disk", 704 + "type": "integer", 705 + "primaryKey": false, 706 + "notNull": false 707 + }, 708 + "status": { 709 + "name": "status", 710 + "type": "text", 711 + "primaryKey": false, 712 + "notNull": true 713 + }, 714 + "keep_alive": { 715 + "name": "keep_alive", 716 + "type": "boolean", 717 + "primaryKey": false, 718 + "notNull": true, 719 + "default": false 720 + }, 721 + "sleep_after": { 722 + "name": "sleep_after", 723 + "type": "text", 724 + "primaryKey": false, 725 + "notNull": false 726 + }, 727 + "sandbox_id": { 728 + "name": "sandbox_id", 729 + "type": "text", 730 + "primaryKey": false, 731 + "notNull": false 732 + }, 733 + "installs": { 734 + "name": "installs", 735 + "type": "integer", 736 + "primaryKey": false, 737 + "notNull": true, 738 + "default": 0 739 + }, 740 + "started_at": { 741 + "name": "started_at", 742 + "type": "timestamp", 743 + "primaryKey": false, 744 + "notNull": false 745 + }, 746 + "created_at": { 747 + "name": "created_at", 748 + "type": "timestamp", 749 + "primaryKey": false, 750 + "notNull": true, 751 + "default": "now()" 752 + }, 753 + "updated_at": { 754 + "name": "updated_at", 755 + "type": "timestamp", 756 + "primaryKey": false, 757 + "notNull": true, 758 + "default": "now()" 759 + } 760 + }, 761 + "indexes": {}, 762 + "foreignKeys": { 763 + "sandboxes_user_id_users_id_fk": { 764 + "name": "sandboxes_user_id_users_id_fk", 765 + "tableFrom": "sandboxes", 766 + "tableTo": "users", 767 + "columnsFrom": [ 768 + "user_id" 769 + ], 770 + "columnsTo": [ 771 + "id" 772 + ], 773 + "onDelete": "no action", 774 + "onUpdate": "no action" 775 + } 776 + }, 777 + "compositePrimaryKeys": {}, 778 + "uniqueConstraints": { 779 + "sandboxes_name_unique": { 780 + "name": "sandboxes_name_unique", 781 + "nullsNotDistinct": false, 782 + "columns": [ 783 + "name" 784 + ] 785 + }, 786 + "sandboxes_uri_unique": { 787 + "name": "sandboxes_uri_unique", 788 + "nullsNotDistinct": false, 789 + "columns": [ 790 + "uri" 791 + ] 792 + }, 793 + "sandboxes_cid_unique": { 794 + "name": "sandboxes_cid_unique", 795 + "nullsNotDistinct": false, 796 + "columns": [ 797 + "cid" 798 + ] 799 + } 800 + }, 801 + "policies": {}, 802 + "checkConstraints": {}, 803 + "isRLSEnabled": false 804 + }, 805 + "public.secrets": { 806 + "name": "secrets", 807 + "schema": "", 808 + "columns": { 809 + "id": { 810 + "name": "id", 811 + "type": "text", 812 + "primaryKey": true, 813 + "notNull": true, 814 + "default": "secret_id()" 815 + }, 816 + "name": { 817 + "name": "name", 818 + "type": "text", 819 + "primaryKey": false, 820 + "notNull": true 821 + }, 822 + "value": { 823 + "name": "value", 824 + "type": "text", 825 + "primaryKey": false, 826 + "notNull": true 827 + }, 828 + "redacted": { 829 + "name": "redacted", 830 + "type": "text", 831 + "primaryKey": false, 832 + "notNull": false 833 + }, 834 + "created_at": { 835 + "name": "created_at", 836 + "type": "timestamp", 837 + "primaryKey": false, 838 + "notNull": true, 839 + "default": "now()" 840 + } 841 + }, 842 + "indexes": {}, 843 + "foreignKeys": {}, 844 + "compositePrimaryKeys": {}, 845 + "uniqueConstraints": {}, 846 + "policies": {}, 847 + "checkConstraints": {}, 848 + "isRLSEnabled": false 849 + }, 850 + "public.snapshots": { 851 + "name": "snapshots", 852 + "schema": "", 853 + "columns": { 854 + "id": { 855 + "name": "id", 856 + "type": "text", 857 + "primaryKey": true, 858 + "notNull": true, 859 + "default": "snapshot_id()" 860 + }, 861 + "slug": { 862 + "name": "slug", 863 + "type": "text", 864 + "primaryKey": false, 865 + "notNull": true 866 + }, 867 + "created_at": { 868 + "name": "created_at", 869 + "type": "timestamp", 870 + "primaryKey": false, 871 + "notNull": true, 872 + "default": "now()" 873 + } 874 + }, 875 + "indexes": {}, 876 + "foreignKeys": {}, 877 + "compositePrimaryKeys": {}, 878 + "uniqueConstraints": { 879 + "snapshots_slug_unique": { 880 + "name": "snapshots_slug_unique", 881 + "nullsNotDistinct": false, 882 + "columns": [ 883 + "slug" 884 + ] 885 + } 886 + }, 887 + "policies": {}, 888 + "checkConstraints": {}, 889 + "isRLSEnabled": false 890 + }, 891 + "public.users": { 892 + "name": "users", 893 + "schema": "", 894 + "columns": { 895 + "id": { 896 + "name": "id", 897 + "type": "text", 898 + "primaryKey": true, 899 + "notNull": true, 900 + "default": "xata_id()" 901 + }, 902 + "did": { 903 + "name": "did", 904 + "type": "text", 905 + "primaryKey": false, 906 + "notNull": true 907 + }, 908 + "display_name": { 909 + "name": "display_name", 910 + "type": "text", 911 + "primaryKey": false, 912 + "notNull": false 913 + }, 914 + "handle": { 915 + "name": "handle", 916 + "type": "text", 917 + "primaryKey": false, 918 + "notNull": true 919 + }, 920 + "avatar": { 921 + "name": "avatar", 922 + "type": "text", 923 + "primaryKey": false, 924 + "notNull": false 925 + }, 926 + "created_at": { 927 + "name": "created_at", 928 + "type": "timestamp", 929 + "primaryKey": false, 930 + "notNull": true, 931 + "default": "now()" 932 + }, 933 + "updated_at": { 934 + "name": "updated_at", 935 + "type": "timestamp", 936 + "primaryKey": false, 937 + "notNull": true, 938 + "default": "now()" 939 + } 940 + }, 941 + "indexes": {}, 942 + "foreignKeys": {}, 943 + "compositePrimaryKeys": {}, 944 + "uniqueConstraints": { 945 + "users_did_unique": { 946 + "name": "users_did_unique", 947 + "nullsNotDistinct": false, 948 + "columns": [ 949 + "did" 950 + ] 951 + }, 952 + "users_handle_unique": { 953 + "name": "users_handle_unique", 954 + "nullsNotDistinct": false, 955 + "columns": [ 956 + "handle" 957 + ] 958 + } 959 + }, 960 + "policies": {}, 961 + "checkConstraints": {}, 962 + "isRLSEnabled": false 963 + }, 964 + "public.variables": { 965 + "name": "variables", 966 + "schema": "", 967 + "columns": { 968 + "id": { 969 + "name": "id", 970 + "type": "text", 971 + "primaryKey": true, 972 + "notNull": true, 973 + "default": "variable_id()" 974 + }, 975 + "name": { 976 + "name": "name", 977 + "type": "text", 978 + "primaryKey": false, 979 + "notNull": true 980 + }, 981 + "value": { 982 + "name": "value", 983 + "type": "text", 984 + "primaryKey": false, 985 + "notNull": true 986 + }, 987 + "created_at": { 988 + "name": "created_at", 989 + "type": "timestamp", 990 + "primaryKey": false, 991 + "notNull": true, 992 + "default": "now()" 993 + }, 994 + "updated_at": { 995 + "name": "updated_at", 996 + "type": "timestamp", 997 + "primaryKey": false, 998 + "notNull": true, 999 + "default": "now()" 1000 + } 1001 + }, 1002 + "indexes": {}, 1003 + "foreignKeys": {}, 1004 + "compositePrimaryKeys": {}, 1005 + "uniqueConstraints": {}, 1006 + "policies": {}, 1007 + "checkConstraints": {}, 1008 + "isRLSEnabled": false 1009 + }, 1010 + "public.volumes": { 1011 + "name": "volumes", 1012 + "schema": "", 1013 + "columns": { 1014 + "id": { 1015 + "name": "id", 1016 + "type": "text", 1017 + "primaryKey": true, 1018 + "notNull": true, 1019 + "default": "volume_id()" 1020 + }, 1021 + "slug": { 1022 + "name": "slug", 1023 + "type": "text", 1024 + "primaryKey": false, 1025 + "notNull": true 1026 + }, 1027 + "size": { 1028 + "name": "size", 1029 + "type": "integer", 1030 + "primaryKey": false, 1031 + "notNull": true 1032 + }, 1033 + "size_unit": { 1034 + "name": "size_unit", 1035 + "type": "text", 1036 + "primaryKey": false, 1037 + "notNull": true 1038 + }, 1039 + "created_at": { 1040 + "name": "created_at", 1041 + "type": "timestamp", 1042 + "primaryKey": false, 1043 + "notNull": true, 1044 + "default": "now()" 1045 + }, 1046 + "updated_at": { 1047 + "name": "updated_at", 1048 + "type": "timestamp", 1049 + "primaryKey": false, 1050 + "notNull": true, 1051 + "default": "now()" 1052 + } 1053 + }, 1054 + "indexes": {}, 1055 + "foreignKeys": {}, 1056 + "compositePrimaryKeys": {}, 1057 + "uniqueConstraints": { 1058 + "volumes_slug_unique": { 1059 + "name": "volumes_slug_unique", 1060 + "nullsNotDistinct": false, 1061 + "columns": [ 1062 + "slug" 1063 + ] 1064 + } 1065 + }, 1066 + "policies": {}, 1067 + "checkConstraints": {}, 1068 + "isRLSEnabled": false 1069 + }, 1070 + "public.integrations": { 1071 + "name": "integrations", 1072 + "schema": "", 1073 + "columns": { 1074 + "id": { 1075 + "name": "id", 1076 + "type": "text", 1077 + "primaryKey": true, 1078 + "notNull": true, 1079 + "default": "xata_id()" 1080 + }, 1081 + "sandbox_id": { 1082 + "name": "sandbox_id", 1083 + "type": "text", 1084 + "primaryKey": false, 1085 + "notNull": true 1086 + }, 1087 + "name": { 1088 + "name": "name", 1089 + "type": "text", 1090 + "primaryKey": false, 1091 + "notNull": true 1092 + }, 1093 + "description": { 1094 + "name": "description", 1095 + "type": "text", 1096 + "primaryKey": false, 1097 + "notNull": false 1098 + }, 1099 + "webhook_url": { 1100 + "name": "webhook_url", 1101 + "type": "text", 1102 + "primaryKey": false, 1103 + "notNull": true 1104 + }, 1105 + "created_at": { 1106 + "name": "created_at", 1107 + "type": "timestamp", 1108 + "primaryKey": false, 1109 + "notNull": true, 1110 + "default": "now()" 1111 + } 1112 + }, 1113 + "indexes": { 1114 + "unique_sandbox_integration": { 1115 + "name": "unique_sandbox_integration", 1116 + "columns": [ 1117 + { 1118 + "expression": "sandbox_id", 1119 + "isExpression": false, 1120 + "asc": true, 1121 + "nulls": "last" 1122 + }, 1123 + { 1124 + "expression": "name", 1125 + "isExpression": false, 1126 + "asc": true, 1127 + "nulls": "last" 1128 + } 1129 + ], 1130 + "isUnique": true, 1131 + "concurrently": false, 1132 + "method": "btree", 1133 + "with": {} 1134 + } 1135 + }, 1136 + "foreignKeys": { 1137 + "integrations_sandbox_id_sandboxes_id_fk": { 1138 + "name": "integrations_sandbox_id_sandboxes_id_fk", 1139 + "tableFrom": "integrations", 1140 + "tableTo": "sandboxes", 1141 + "columnsFrom": [ 1142 + "sandbox_id" 1143 + ], 1144 + "columnsTo": [ 1145 + "id" 1146 + ], 1147 + "onDelete": "no action", 1148 + "onUpdate": "no action" 1149 + } 1150 + }, 1151 + "compositePrimaryKeys": {}, 1152 + "uniqueConstraints": {}, 1153 + "policies": {}, 1154 + "checkConstraints": {}, 1155 + "isRLSEnabled": false 1156 + }, 1157 + "public.ssh_keys": { 1158 + "name": "ssh_keys", 1159 + "schema": "", 1160 + "columns": { 1161 + "id": { 1162 + "name": "id", 1163 + "type": "text", 1164 + "primaryKey": true, 1165 + "notNull": true, 1166 + "default": "xata_id()" 1167 + }, 1168 + "sandbox_id": { 1169 + "name": "sandbox_id", 1170 + "type": "text", 1171 + "primaryKey": false, 1172 + "notNull": true 1173 + }, 1174 + "public_key": { 1175 + "name": "public_key", 1176 + "type": "text", 1177 + "primaryKey": false, 1178 + "notNull": true 1179 + }, 1180 + "private_key": { 1181 + "name": "private_key", 1182 + "type": "text", 1183 + "primaryKey": false, 1184 + "notNull": true 1185 + }, 1186 + "redacted": { 1187 + "name": "redacted", 1188 + "type": "text", 1189 + "primaryKey": false, 1190 + "notNull": true 1191 + }, 1192 + "created_at": { 1193 + "name": "created_at", 1194 + "type": "timestamp", 1195 + "primaryKey": false, 1196 + "notNull": true, 1197 + "default": "now()" 1198 + } 1199 + }, 1200 + "indexes": {}, 1201 + "foreignKeys": { 1202 + "ssh_keys_sandbox_id_sandboxes_id_fk": { 1203 + "name": "ssh_keys_sandbox_id_sandboxes_id_fk", 1204 + "tableFrom": "ssh_keys", 1205 + "tableTo": "sandboxes", 1206 + "columnsFrom": [ 1207 + "sandbox_id" 1208 + ], 1209 + "columnsTo": [ 1210 + "id" 1211 + ], 1212 + "onDelete": "no action", 1213 + "onUpdate": "no action" 1214 + } 1215 + }, 1216 + "compositePrimaryKeys": {}, 1217 + "uniqueConstraints": {}, 1218 + "policies": {}, 1219 + "checkConstraints": {}, 1220 + "isRLSEnabled": false 1221 + }, 1222 + "public.tailscale_tokens": { 1223 + "name": "tailscale_tokens", 1224 + "schema": "", 1225 + "columns": { 1226 + "id": { 1227 + "name": "id", 1228 + "type": "text", 1229 + "primaryKey": true, 1230 + "notNull": true, 1231 + "default": "xata_id()" 1232 + }, 1233 + "sandbox_id": { 1234 + "name": "sandbox_id", 1235 + "type": "text", 1236 + "primaryKey": false, 1237 + "notNull": false 1238 + }, 1239 + "tokens": { 1240 + "name": "tokens", 1241 + "type": "text", 1242 + "primaryKey": false, 1243 + "notNull": true 1244 + }, 1245 + "redacted": { 1246 + "name": "redacted", 1247 + "type": "text", 1248 + "primaryKey": false, 1249 + "notNull": true 1250 + }, 1251 + "created_at": { 1252 + "name": "created_at", 1253 + "type": "timestamp", 1254 + "primaryKey": false, 1255 + "notNull": true, 1256 + "default": "now()" 1257 + } 1258 + }, 1259 + "indexes": {}, 1260 + "foreignKeys": { 1261 + "tailscale_tokens_sandbox_id_sandboxes_id_fk": { 1262 + "name": "tailscale_tokens_sandbox_id_sandboxes_id_fk", 1263 + "tableFrom": "tailscale_tokens", 1264 + "tableTo": "sandboxes", 1265 + "columnsFrom": [ 1266 + "sandbox_id" 1267 + ], 1268 + "columnsTo": [ 1269 + "id" 1270 + ], 1271 + "onDelete": "no action", 1272 + "onUpdate": "no action" 1273 + } 1274 + }, 1275 + "compositePrimaryKeys": {}, 1276 + "uniqueConstraints": {}, 1277 + "policies": {}, 1278 + "checkConstraints": {}, 1279 + "isRLSEnabled": false 1280 + } 1281 + }, 1282 + "enums": {}, 1283 + "schemas": {}, 1284 + "sequences": {}, 1285 + "roles": {}, 1286 + "policies": {}, 1287 + "views": {}, 1288 + "_meta": { 1289 + "columns": {}, 1290 + "schemas": {}, 1291 + "tables": {} 1292 + } 1293 + }
+1293
apps/cf-sandbox/drizzle/meta/0023_snapshot.json
··· 1 + { 2 + "id": "531aceb3-0e05-435c-bbaf-50a671078d58", 3 + "prevId": "3bfd8c5c-cb46-4e30-bce1-4ea9bae3935f", 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": "variable_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": "xata_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": { 146 + "name": "unique_sandbox_file", 147 + "columns": [ 148 + { 149 + "expression": "sandbox_id", 150 + "isExpression": false, 151 + "asc": true, 152 + "nulls": "last" 153 + }, 154 + { 155 + "expression": "file_id", 156 + "isExpression": false, 157 + "asc": true, 158 + "nulls": "last" 159 + } 160 + ], 161 + "isUnique": true, 162 + "concurrently": false, 163 + "method": "btree", 164 + "with": {} 165 + }, 166 + "unique_sandbox_file_path": { 167 + "name": "unique_sandbox_file_path", 168 + "columns": [ 169 + { 170 + "expression": "sandbox_id", 171 + "isExpression": false, 172 + "asc": true, 173 + "nulls": "last" 174 + }, 175 + { 176 + "expression": "path", 177 + "isExpression": false, 178 + "asc": true, 179 + "nulls": "last" 180 + } 181 + ], 182 + "isUnique": true, 183 + "concurrently": false, 184 + "method": "btree", 185 + "with": {} 186 + } 187 + }, 188 + "foreignKeys": { 189 + "sandbox_files_sandbox_id_sandboxes_id_fk": { 190 + "name": "sandbox_files_sandbox_id_sandboxes_id_fk", 191 + "tableFrom": "sandbox_files", 192 + "tableTo": "sandboxes", 193 + "columnsFrom": [ 194 + "sandbox_id" 195 + ], 196 + "columnsTo": [ 197 + "id" 198 + ], 199 + "onDelete": "no action", 200 + "onUpdate": "no action" 201 + }, 202 + "sandbox_files_file_id_files_id_fk": { 203 + "name": "sandbox_files_file_id_files_id_fk", 204 + "tableFrom": "sandbox_files", 205 + "tableTo": "files", 206 + "columnsFrom": [ 207 + "file_id" 208 + ], 209 + "columnsTo": [ 210 + "id" 211 + ], 212 + "onDelete": "no action", 213 + "onUpdate": "no action" 214 + } 215 + }, 216 + "compositePrimaryKeys": {}, 217 + "uniqueConstraints": {}, 218 + "policies": {}, 219 + "checkConstraints": {}, 220 + "isRLSEnabled": false 221 + }, 222 + "public.sandbox_secrets": { 223 + "name": "sandbox_secrets", 224 + "schema": "", 225 + "columns": { 226 + "id": { 227 + "name": "id", 228 + "type": "text", 229 + "primaryKey": true, 230 + "notNull": true, 231 + "default": "xata_id()" 232 + }, 233 + "sandbox_id": { 234 + "name": "sandbox_id", 235 + "type": "text", 236 + "primaryKey": false, 237 + "notNull": true 238 + }, 239 + "secret_id": { 240 + "name": "secret_id", 241 + "type": "text", 242 + "primaryKey": false, 243 + "notNull": true 244 + }, 245 + "name": { 246 + "name": "name", 247 + "type": "text", 248 + "primaryKey": false, 249 + "notNull": false 250 + }, 251 + "created_at": { 252 + "name": "created_at", 253 + "type": "timestamp", 254 + "primaryKey": false, 255 + "notNull": true, 256 + "default": "now()" 257 + }, 258 + "updated_at": { 259 + "name": "updated_at", 260 + "type": "timestamp", 261 + "primaryKey": false, 262 + "notNull": true, 263 + "default": "now()" 264 + } 265 + }, 266 + "indexes": { 267 + "unique_sandbox_secret": { 268 + "name": "unique_sandbox_secret", 269 + "columns": [ 270 + { 271 + "expression": "sandbox_id", 272 + "isExpression": false, 273 + "asc": true, 274 + "nulls": "last" 275 + }, 276 + { 277 + "expression": "secret_id", 278 + "isExpression": false, 279 + "asc": true, 280 + "nulls": "last" 281 + } 282 + ], 283 + "isUnique": true, 284 + "concurrently": false, 285 + "method": "btree", 286 + "with": {} 287 + }, 288 + "unique_sandbox_secret_by_name": { 289 + "name": "unique_sandbox_secret_by_name", 290 + "columns": [ 291 + { 292 + "expression": "sandbox_id", 293 + "isExpression": false, 294 + "asc": true, 295 + "nulls": "last" 296 + }, 297 + { 298 + "expression": "name", 299 + "isExpression": false, 300 + "asc": true, 301 + "nulls": "last" 302 + } 303 + ], 304 + "isUnique": true, 305 + "concurrently": false, 306 + "method": "btree", 307 + "with": {} 308 + } 309 + }, 310 + "foreignKeys": { 311 + "sandbox_secrets_sandbox_id_sandboxes_id_fk": { 312 + "name": "sandbox_secrets_sandbox_id_sandboxes_id_fk", 313 + "tableFrom": "sandbox_secrets", 314 + "tableTo": "sandboxes", 315 + "columnsFrom": [ 316 + "sandbox_id" 317 + ], 318 + "columnsTo": [ 319 + "id" 320 + ], 321 + "onDelete": "no action", 322 + "onUpdate": "no action" 323 + }, 324 + "sandbox_secrets_secret_id_secrets_id_fk": { 325 + "name": "sandbox_secrets_secret_id_secrets_id_fk", 326 + "tableFrom": "sandbox_secrets", 327 + "tableTo": "secrets", 328 + "columnsFrom": [ 329 + "secret_id" 330 + ], 331 + "columnsTo": [ 332 + "id" 333 + ], 334 + "onDelete": "no action", 335 + "onUpdate": "no action" 336 + } 337 + }, 338 + "compositePrimaryKeys": {}, 339 + "uniqueConstraints": {}, 340 + "policies": {}, 341 + "checkConstraints": {}, 342 + "isRLSEnabled": false 343 + }, 344 + "public.sandbox_variables": { 345 + "name": "sandbox_variables", 346 + "schema": "", 347 + "columns": { 348 + "id": { 349 + "name": "id", 350 + "type": "text", 351 + "primaryKey": true, 352 + "notNull": true, 353 + "default": "xata_id()" 354 + }, 355 + "sandbox_id": { 356 + "name": "sandbox_id", 357 + "type": "text", 358 + "primaryKey": false, 359 + "notNull": true 360 + }, 361 + "variable_id": { 362 + "name": "variable_id", 363 + "type": "text", 364 + "primaryKey": false, 365 + "notNull": true 366 + }, 367 + "name": { 368 + "name": "name", 369 + "type": "text", 370 + "primaryKey": false, 371 + "notNull": true 372 + }, 373 + "created_at": { 374 + "name": "created_at", 375 + "type": "timestamp", 376 + "primaryKey": false, 377 + "notNull": true, 378 + "default": "now()" 379 + }, 380 + "updated_at": { 381 + "name": "updated_at", 382 + "type": "timestamp", 383 + "primaryKey": false, 384 + "notNull": true, 385 + "default": "now()" 386 + } 387 + }, 388 + "indexes": { 389 + "unique_sandbox_variables": { 390 + "name": "unique_sandbox_variables", 391 + "columns": [ 392 + { 393 + "expression": "sandbox_id", 394 + "isExpression": false, 395 + "asc": true, 396 + "nulls": "last" 397 + }, 398 + { 399 + "expression": "variable_id", 400 + "isExpression": false, 401 + "asc": true, 402 + "nulls": "last" 403 + } 404 + ], 405 + "isUnique": true, 406 + "concurrently": false, 407 + "method": "btree", 408 + "with": {} 409 + }, 410 + "unique_sandbox_variables_by_name": { 411 + "name": "unique_sandbox_variables_by_name", 412 + "columns": [ 413 + { 414 + "expression": "sandbox_id", 415 + "isExpression": false, 416 + "asc": true, 417 + "nulls": "last" 418 + }, 419 + { 420 + "expression": "name", 421 + "isExpression": false, 422 + "asc": true, 423 + "nulls": "last" 424 + } 425 + ], 426 + "isUnique": true, 427 + "concurrently": false, 428 + "method": "btree", 429 + "with": {} 430 + } 431 + }, 432 + "foreignKeys": { 433 + "sandbox_variables_sandbox_id_sandboxes_id_fk": { 434 + "name": "sandbox_variables_sandbox_id_sandboxes_id_fk", 435 + "tableFrom": "sandbox_variables", 436 + "tableTo": "sandboxes", 437 + "columnsFrom": [ 438 + "sandbox_id" 439 + ], 440 + "columnsTo": [ 441 + "id" 442 + ], 443 + "onDelete": "no action", 444 + "onUpdate": "no action" 445 + }, 446 + "sandbox_variables_variable_id_variables_id_fk": { 447 + "name": "sandbox_variables_variable_id_variables_id_fk", 448 + "tableFrom": "sandbox_variables", 449 + "tableTo": "variables", 450 + "columnsFrom": [ 451 + "variable_id" 452 + ], 453 + "columnsTo": [ 454 + "id" 455 + ], 456 + "onDelete": "no action", 457 + "onUpdate": "no action" 458 + } 459 + }, 460 + "compositePrimaryKeys": {}, 461 + "uniqueConstraints": {}, 462 + "policies": {}, 463 + "checkConstraints": {}, 464 + "isRLSEnabled": false 465 + }, 466 + "public.sandbox_volumes": { 467 + "name": "sandbox_volumes", 468 + "schema": "", 469 + "columns": { 470 + "id": { 471 + "name": "id", 472 + "type": "text", 473 + "primaryKey": true, 474 + "notNull": true, 475 + "default": "xata_id()" 476 + }, 477 + "sandbox_id": { 478 + "name": "sandbox_id", 479 + "type": "text", 480 + "primaryKey": false, 481 + "notNull": true 482 + }, 483 + "volume_id": { 484 + "name": "volume_id", 485 + "type": "text", 486 + "primaryKey": false, 487 + "notNull": true 488 + }, 489 + "name": { 490 + "name": "name", 491 + "type": "text", 492 + "primaryKey": false, 493 + "notNull": false 494 + }, 495 + "path": { 496 + "name": "path", 497 + "type": "text", 498 + "primaryKey": false, 499 + "notNull": true 500 + }, 501 + "created_at": { 502 + "name": "created_at", 503 + "type": "timestamp", 504 + "primaryKey": false, 505 + "notNull": true, 506 + "default": "now()" 507 + }, 508 + "updated_at": { 509 + "name": "updated_at", 510 + "type": "timestamp", 511 + "primaryKey": false, 512 + "notNull": true, 513 + "default": "now()" 514 + } 515 + }, 516 + "indexes": { 517 + "unique_sandbox_volume": { 518 + "name": "unique_sandbox_volume", 519 + "columns": [ 520 + { 521 + "expression": "sandbox_id", 522 + "isExpression": false, 523 + "asc": true, 524 + "nulls": "last" 525 + }, 526 + { 527 + "expression": "volume_id", 528 + "isExpression": false, 529 + "asc": true, 530 + "nulls": "last" 531 + } 532 + ], 533 + "isUnique": true, 534 + "concurrently": false, 535 + "method": "btree", 536 + "with": {} 537 + }, 538 + "unique_sandbox_volume_path": { 539 + "name": "unique_sandbox_volume_path", 540 + "columns": [ 541 + { 542 + "expression": "sandbox_id", 543 + "isExpression": false, 544 + "asc": true, 545 + "nulls": "last" 546 + }, 547 + { 548 + "expression": "path", 549 + "isExpression": false, 550 + "asc": true, 551 + "nulls": "last" 552 + } 553 + ], 554 + "isUnique": true, 555 + "concurrently": false, 556 + "method": "btree", 557 + "with": {} 558 + } 559 + }, 560 + "foreignKeys": { 561 + "sandbox_volumes_sandbox_id_sandboxes_id_fk": { 562 + "name": "sandbox_volumes_sandbox_id_sandboxes_id_fk", 563 + "tableFrom": "sandbox_volumes", 564 + "tableTo": "sandboxes", 565 + "columnsFrom": [ 566 + "sandbox_id" 567 + ], 568 + "columnsTo": [ 569 + "id" 570 + ], 571 + "onDelete": "no action", 572 + "onUpdate": "no action" 573 + }, 574 + "sandbox_volumes_volume_id_volumes_id_fk": { 575 + "name": "sandbox_volumes_volume_id_volumes_id_fk", 576 + "tableFrom": "sandbox_volumes", 577 + "tableTo": "volumes", 578 + "columnsFrom": [ 579 + "volume_id" 580 + ], 581 + "columnsTo": [ 582 + "id" 583 + ], 584 + "onDelete": "no action", 585 + "onUpdate": "no action" 586 + } 587 + }, 588 + "compositePrimaryKeys": {}, 589 + "uniqueConstraints": {}, 590 + "policies": {}, 591 + "checkConstraints": {}, 592 + "isRLSEnabled": false 593 + }, 594 + "public.sandboxes": { 595 + "name": "sandboxes", 596 + "schema": "", 597 + "columns": { 598 + "id": { 599 + "name": "id", 600 + "type": "text", 601 + "primaryKey": true, 602 + "notNull": true, 603 + "default": "sandbox_id()" 604 + }, 605 + "base": { 606 + "name": "base", 607 + "type": "text", 608 + "primaryKey": false, 609 + "notNull": false 610 + }, 611 + "name": { 612 + "name": "name", 613 + "type": "text", 614 + "primaryKey": false, 615 + "notNull": true 616 + }, 617 + "display_name": { 618 + "name": "display_name", 619 + "type": "text", 620 + "primaryKey": false, 621 + "notNull": false 622 + }, 623 + "uri": { 624 + "name": "uri", 625 + "type": "text", 626 + "primaryKey": false, 627 + "notNull": false 628 + }, 629 + "cid": { 630 + "name": "cid", 631 + "type": "text", 632 + "primaryKey": false, 633 + "notNull": false 634 + }, 635 + "repo": { 636 + "name": "repo", 637 + "type": "text", 638 + "primaryKey": false, 639 + "notNull": false 640 + }, 641 + "provider": { 642 + "name": "provider", 643 + "type": "text", 644 + "primaryKey": false, 645 + "notNull": true, 646 + "default": "'cloudflare'" 647 + }, 648 + "description": { 649 + "name": "description", 650 + "type": "text", 651 + "primaryKey": false, 652 + "notNull": false 653 + }, 654 + "topics": { 655 + "name": "topics", 656 + "type": "text[]", 657 + "primaryKey": false, 658 + "notNull": false 659 + }, 660 + "logo": { 661 + "name": "logo", 662 + "type": "text", 663 + "primaryKey": false, 664 + "notNull": false 665 + }, 666 + "readme": { 667 + "name": "readme", 668 + "type": "text", 669 + "primaryKey": false, 670 + "notNull": false 671 + }, 672 + "public_key": { 673 + "name": "public_key", 674 + "type": "text", 675 + "primaryKey": false, 676 + "notNull": true 677 + }, 678 + "user_id": { 679 + "name": "user_id", 680 + "type": "text", 681 + "primaryKey": false, 682 + "notNull": false 683 + }, 684 + "instance_type": { 685 + "name": "instance_type", 686 + "type": "text", 687 + "primaryKey": false, 688 + "notNull": false 689 + }, 690 + "vcpus": { 691 + "name": "vcpus", 692 + "type": "integer", 693 + "primaryKey": false, 694 + "notNull": false 695 + }, 696 + "memory": { 697 + "name": "memory", 698 + "type": "integer", 699 + "primaryKey": false, 700 + "notNull": false 701 + }, 702 + "disk": { 703 + "name": "disk", 704 + "type": "integer", 705 + "primaryKey": false, 706 + "notNull": false 707 + }, 708 + "status": { 709 + "name": "status", 710 + "type": "text", 711 + "primaryKey": false, 712 + "notNull": true 713 + }, 714 + "keep_alive": { 715 + "name": "keep_alive", 716 + "type": "boolean", 717 + "primaryKey": false, 718 + "notNull": true, 719 + "default": false 720 + }, 721 + "sleep_after": { 722 + "name": "sleep_after", 723 + "type": "text", 724 + "primaryKey": false, 725 + "notNull": false 726 + }, 727 + "sandbox_id": { 728 + "name": "sandbox_id", 729 + "type": "text", 730 + "primaryKey": false, 731 + "notNull": false 732 + }, 733 + "installs": { 734 + "name": "installs", 735 + "type": "integer", 736 + "primaryKey": false, 737 + "notNull": true, 738 + "default": 0 739 + }, 740 + "started_at": { 741 + "name": "started_at", 742 + "type": "timestamp", 743 + "primaryKey": false, 744 + "notNull": false 745 + }, 746 + "created_at": { 747 + "name": "created_at", 748 + "type": "timestamp", 749 + "primaryKey": false, 750 + "notNull": true, 751 + "default": "now()" 752 + }, 753 + "updated_at": { 754 + "name": "updated_at", 755 + "type": "timestamp", 756 + "primaryKey": false, 757 + "notNull": true, 758 + "default": "now()" 759 + } 760 + }, 761 + "indexes": {}, 762 + "foreignKeys": { 763 + "sandboxes_user_id_users_id_fk": { 764 + "name": "sandboxes_user_id_users_id_fk", 765 + "tableFrom": "sandboxes", 766 + "tableTo": "users", 767 + "columnsFrom": [ 768 + "user_id" 769 + ], 770 + "columnsTo": [ 771 + "id" 772 + ], 773 + "onDelete": "no action", 774 + "onUpdate": "no action" 775 + } 776 + }, 777 + "compositePrimaryKeys": {}, 778 + "uniqueConstraints": { 779 + "sandboxes_name_unique": { 780 + "name": "sandboxes_name_unique", 781 + "nullsNotDistinct": false, 782 + "columns": [ 783 + "name" 784 + ] 785 + }, 786 + "sandboxes_uri_unique": { 787 + "name": "sandboxes_uri_unique", 788 + "nullsNotDistinct": false, 789 + "columns": [ 790 + "uri" 791 + ] 792 + }, 793 + "sandboxes_cid_unique": { 794 + "name": "sandboxes_cid_unique", 795 + "nullsNotDistinct": false, 796 + "columns": [ 797 + "cid" 798 + ] 799 + } 800 + }, 801 + "policies": {}, 802 + "checkConstraints": {}, 803 + "isRLSEnabled": false 804 + }, 805 + "public.secrets": { 806 + "name": "secrets", 807 + "schema": "", 808 + "columns": { 809 + "id": { 810 + "name": "id", 811 + "type": "text", 812 + "primaryKey": true, 813 + "notNull": true, 814 + "default": "secret_id()" 815 + }, 816 + "name": { 817 + "name": "name", 818 + "type": "text", 819 + "primaryKey": false, 820 + "notNull": true 821 + }, 822 + "value": { 823 + "name": "value", 824 + "type": "text", 825 + "primaryKey": false, 826 + "notNull": true 827 + }, 828 + "redacted": { 829 + "name": "redacted", 830 + "type": "text", 831 + "primaryKey": false, 832 + "notNull": false 833 + }, 834 + "created_at": { 835 + "name": "created_at", 836 + "type": "timestamp", 837 + "primaryKey": false, 838 + "notNull": true, 839 + "default": "now()" 840 + } 841 + }, 842 + "indexes": {}, 843 + "foreignKeys": {}, 844 + "compositePrimaryKeys": {}, 845 + "uniqueConstraints": {}, 846 + "policies": {}, 847 + "checkConstraints": {}, 848 + "isRLSEnabled": false 849 + }, 850 + "public.snapshots": { 851 + "name": "snapshots", 852 + "schema": "", 853 + "columns": { 854 + "id": { 855 + "name": "id", 856 + "type": "text", 857 + "primaryKey": true, 858 + "notNull": true, 859 + "default": "snapshot_id()" 860 + }, 861 + "slug": { 862 + "name": "slug", 863 + "type": "text", 864 + "primaryKey": false, 865 + "notNull": true 866 + }, 867 + "created_at": { 868 + "name": "created_at", 869 + "type": "timestamp", 870 + "primaryKey": false, 871 + "notNull": true, 872 + "default": "now()" 873 + } 874 + }, 875 + "indexes": {}, 876 + "foreignKeys": {}, 877 + "compositePrimaryKeys": {}, 878 + "uniqueConstraints": { 879 + "snapshots_slug_unique": { 880 + "name": "snapshots_slug_unique", 881 + "nullsNotDistinct": false, 882 + "columns": [ 883 + "slug" 884 + ] 885 + } 886 + }, 887 + "policies": {}, 888 + "checkConstraints": {}, 889 + "isRLSEnabled": false 890 + }, 891 + "public.users": { 892 + "name": "users", 893 + "schema": "", 894 + "columns": { 895 + "id": { 896 + "name": "id", 897 + "type": "text", 898 + "primaryKey": true, 899 + "notNull": true, 900 + "default": "xata_id()" 901 + }, 902 + "did": { 903 + "name": "did", 904 + "type": "text", 905 + "primaryKey": false, 906 + "notNull": true 907 + }, 908 + "display_name": { 909 + "name": "display_name", 910 + "type": "text", 911 + "primaryKey": false, 912 + "notNull": false 913 + }, 914 + "handle": { 915 + "name": "handle", 916 + "type": "text", 917 + "primaryKey": false, 918 + "notNull": true 919 + }, 920 + "avatar": { 921 + "name": "avatar", 922 + "type": "text", 923 + "primaryKey": false, 924 + "notNull": false 925 + }, 926 + "created_at": { 927 + "name": "created_at", 928 + "type": "timestamp", 929 + "primaryKey": false, 930 + "notNull": true, 931 + "default": "now()" 932 + }, 933 + "updated_at": { 934 + "name": "updated_at", 935 + "type": "timestamp", 936 + "primaryKey": false, 937 + "notNull": true, 938 + "default": "now()" 939 + } 940 + }, 941 + "indexes": {}, 942 + "foreignKeys": {}, 943 + "compositePrimaryKeys": {}, 944 + "uniqueConstraints": { 945 + "users_did_unique": { 946 + "name": "users_did_unique", 947 + "nullsNotDistinct": false, 948 + "columns": [ 949 + "did" 950 + ] 951 + }, 952 + "users_handle_unique": { 953 + "name": "users_handle_unique", 954 + "nullsNotDistinct": false, 955 + "columns": [ 956 + "handle" 957 + ] 958 + } 959 + }, 960 + "policies": {}, 961 + "checkConstraints": {}, 962 + "isRLSEnabled": false 963 + }, 964 + "public.variables": { 965 + "name": "variables", 966 + "schema": "", 967 + "columns": { 968 + "id": { 969 + "name": "id", 970 + "type": "text", 971 + "primaryKey": true, 972 + "notNull": true, 973 + "default": "variable_id()" 974 + }, 975 + "name": { 976 + "name": "name", 977 + "type": "text", 978 + "primaryKey": false, 979 + "notNull": true 980 + }, 981 + "value": { 982 + "name": "value", 983 + "type": "text", 984 + "primaryKey": false, 985 + "notNull": true 986 + }, 987 + "created_at": { 988 + "name": "created_at", 989 + "type": "timestamp", 990 + "primaryKey": false, 991 + "notNull": true, 992 + "default": "now()" 993 + }, 994 + "updated_at": { 995 + "name": "updated_at", 996 + "type": "timestamp", 997 + "primaryKey": false, 998 + "notNull": true, 999 + "default": "now()" 1000 + } 1001 + }, 1002 + "indexes": {}, 1003 + "foreignKeys": {}, 1004 + "compositePrimaryKeys": {}, 1005 + "uniqueConstraints": {}, 1006 + "policies": {}, 1007 + "checkConstraints": {}, 1008 + "isRLSEnabled": false 1009 + }, 1010 + "public.volumes": { 1011 + "name": "volumes", 1012 + "schema": "", 1013 + "columns": { 1014 + "id": { 1015 + "name": "id", 1016 + "type": "text", 1017 + "primaryKey": true, 1018 + "notNull": true, 1019 + "default": "volume_id()" 1020 + }, 1021 + "slug": { 1022 + "name": "slug", 1023 + "type": "text", 1024 + "primaryKey": false, 1025 + "notNull": true 1026 + }, 1027 + "size": { 1028 + "name": "size", 1029 + "type": "integer", 1030 + "primaryKey": false, 1031 + "notNull": true 1032 + }, 1033 + "size_unit": { 1034 + "name": "size_unit", 1035 + "type": "text", 1036 + "primaryKey": false, 1037 + "notNull": true 1038 + }, 1039 + "created_at": { 1040 + "name": "created_at", 1041 + "type": "timestamp", 1042 + "primaryKey": false, 1043 + "notNull": true, 1044 + "default": "now()" 1045 + }, 1046 + "updated_at": { 1047 + "name": "updated_at", 1048 + "type": "timestamp", 1049 + "primaryKey": false, 1050 + "notNull": true, 1051 + "default": "now()" 1052 + } 1053 + }, 1054 + "indexes": {}, 1055 + "foreignKeys": {}, 1056 + "compositePrimaryKeys": {}, 1057 + "uniqueConstraints": { 1058 + "volumes_slug_unique": { 1059 + "name": "volumes_slug_unique", 1060 + "nullsNotDistinct": false, 1061 + "columns": [ 1062 + "slug" 1063 + ] 1064 + } 1065 + }, 1066 + "policies": {}, 1067 + "checkConstraints": {}, 1068 + "isRLSEnabled": false 1069 + }, 1070 + "public.integrations": { 1071 + "name": "integrations", 1072 + "schema": "", 1073 + "columns": { 1074 + "id": { 1075 + "name": "id", 1076 + "type": "text", 1077 + "primaryKey": true, 1078 + "notNull": true, 1079 + "default": "xata_id()" 1080 + }, 1081 + "sandbox_id": { 1082 + "name": "sandbox_id", 1083 + "type": "text", 1084 + "primaryKey": false, 1085 + "notNull": true 1086 + }, 1087 + "name": { 1088 + "name": "name", 1089 + "type": "text", 1090 + "primaryKey": false, 1091 + "notNull": true 1092 + }, 1093 + "description": { 1094 + "name": "description", 1095 + "type": "text", 1096 + "primaryKey": false, 1097 + "notNull": false 1098 + }, 1099 + "webhook_url": { 1100 + "name": "webhook_url", 1101 + "type": "text", 1102 + "primaryKey": false, 1103 + "notNull": true 1104 + }, 1105 + "created_at": { 1106 + "name": "created_at", 1107 + "type": "timestamp", 1108 + "primaryKey": false, 1109 + "notNull": true, 1110 + "default": "now()" 1111 + } 1112 + }, 1113 + "indexes": { 1114 + "unique_sandbox_integration": { 1115 + "name": "unique_sandbox_integration", 1116 + "columns": [ 1117 + { 1118 + "expression": "sandbox_id", 1119 + "isExpression": false, 1120 + "asc": true, 1121 + "nulls": "last" 1122 + }, 1123 + { 1124 + "expression": "name", 1125 + "isExpression": false, 1126 + "asc": true, 1127 + "nulls": "last" 1128 + } 1129 + ], 1130 + "isUnique": true, 1131 + "concurrently": false, 1132 + "method": "btree", 1133 + "with": {} 1134 + } 1135 + }, 1136 + "foreignKeys": { 1137 + "integrations_sandbox_id_sandboxes_id_fk": { 1138 + "name": "integrations_sandbox_id_sandboxes_id_fk", 1139 + "tableFrom": "integrations", 1140 + "tableTo": "sandboxes", 1141 + "columnsFrom": [ 1142 + "sandbox_id" 1143 + ], 1144 + "columnsTo": [ 1145 + "id" 1146 + ], 1147 + "onDelete": "no action", 1148 + "onUpdate": "no action" 1149 + } 1150 + }, 1151 + "compositePrimaryKeys": {}, 1152 + "uniqueConstraints": {}, 1153 + "policies": {}, 1154 + "checkConstraints": {}, 1155 + "isRLSEnabled": false 1156 + }, 1157 + "public.ssh_keys": { 1158 + "name": "ssh_keys", 1159 + "schema": "", 1160 + "columns": { 1161 + "id": { 1162 + "name": "id", 1163 + "type": "text", 1164 + "primaryKey": true, 1165 + "notNull": true, 1166 + "default": "xata_id()" 1167 + }, 1168 + "sandbox_id": { 1169 + "name": "sandbox_id", 1170 + "type": "text", 1171 + "primaryKey": false, 1172 + "notNull": true 1173 + }, 1174 + "public_key": { 1175 + "name": "public_key", 1176 + "type": "text", 1177 + "primaryKey": false, 1178 + "notNull": true 1179 + }, 1180 + "private_key": { 1181 + "name": "private_key", 1182 + "type": "text", 1183 + "primaryKey": false, 1184 + "notNull": true 1185 + }, 1186 + "redacted": { 1187 + "name": "redacted", 1188 + "type": "text", 1189 + "primaryKey": false, 1190 + "notNull": false 1191 + }, 1192 + "created_at": { 1193 + "name": "created_at", 1194 + "type": "timestamp", 1195 + "primaryKey": false, 1196 + "notNull": true, 1197 + "default": "now()" 1198 + } 1199 + }, 1200 + "indexes": {}, 1201 + "foreignKeys": { 1202 + "ssh_keys_sandbox_id_sandboxes_id_fk": { 1203 + "name": "ssh_keys_sandbox_id_sandboxes_id_fk", 1204 + "tableFrom": "ssh_keys", 1205 + "tableTo": "sandboxes", 1206 + "columnsFrom": [ 1207 + "sandbox_id" 1208 + ], 1209 + "columnsTo": [ 1210 + "id" 1211 + ], 1212 + "onDelete": "no action", 1213 + "onUpdate": "no action" 1214 + } 1215 + }, 1216 + "compositePrimaryKeys": {}, 1217 + "uniqueConstraints": {}, 1218 + "policies": {}, 1219 + "checkConstraints": {}, 1220 + "isRLSEnabled": false 1221 + }, 1222 + "public.tailscale_tokens": { 1223 + "name": "tailscale_tokens", 1224 + "schema": "", 1225 + "columns": { 1226 + "id": { 1227 + "name": "id", 1228 + "type": "text", 1229 + "primaryKey": true, 1230 + "notNull": true, 1231 + "default": "xata_id()" 1232 + }, 1233 + "sandbox_id": { 1234 + "name": "sandbox_id", 1235 + "type": "text", 1236 + "primaryKey": false, 1237 + "notNull": false 1238 + }, 1239 + "tokens": { 1240 + "name": "tokens", 1241 + "type": "text", 1242 + "primaryKey": false, 1243 + "notNull": true 1244 + }, 1245 + "redacted": { 1246 + "name": "redacted", 1247 + "type": "text", 1248 + "primaryKey": false, 1249 + "notNull": true 1250 + }, 1251 + "created_at": { 1252 + "name": "created_at", 1253 + "type": "timestamp", 1254 + "primaryKey": false, 1255 + "notNull": true, 1256 + "default": "now()" 1257 + } 1258 + }, 1259 + "indexes": {}, 1260 + "foreignKeys": { 1261 + "tailscale_tokens_sandbox_id_sandboxes_id_fk": { 1262 + "name": "tailscale_tokens_sandbox_id_sandboxes_id_fk", 1263 + "tableFrom": "tailscale_tokens", 1264 + "tableTo": "sandboxes", 1265 + "columnsFrom": [ 1266 + "sandbox_id" 1267 + ], 1268 + "columnsTo": [ 1269 + "id" 1270 + ], 1271 + "onDelete": "no action", 1272 + "onUpdate": "no action" 1273 + } 1274 + }, 1275 + "compositePrimaryKeys": {}, 1276 + "uniqueConstraints": {}, 1277 + "policies": {}, 1278 + "checkConstraints": {}, 1279 + "isRLSEnabled": false 1280 + } 1281 + }, 1282 + "enums": {}, 1283 + "schemas": {}, 1284 + "sequences": {}, 1285 + "roles": {}, 1286 + "policies": {}, 1287 + "views": {}, 1288 + "_meta": { 1289 + "columns": {}, 1290 + "schemas": {}, 1291 + "tables": {} 1292 + } 1293 + }
+1315
apps/cf-sandbox/drizzle/meta/0024_snapshot.json
··· 1 + { 2 + "id": "fd9f2cf3-2b96-4f64-a06a-1984ed7647fd", 3 + "prevId": "531aceb3-0e05-435c-bbaf-50a671078d58", 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": "variable_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": "xata_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": { 146 + "name": "unique_sandbox_file", 147 + "columns": [ 148 + { 149 + "expression": "sandbox_id", 150 + "isExpression": false, 151 + "asc": true, 152 + "nulls": "last" 153 + }, 154 + { 155 + "expression": "file_id", 156 + "isExpression": false, 157 + "asc": true, 158 + "nulls": "last" 159 + } 160 + ], 161 + "isUnique": true, 162 + "concurrently": false, 163 + "method": "btree", 164 + "with": {} 165 + }, 166 + "unique_sandbox_file_path": { 167 + "name": "unique_sandbox_file_path", 168 + "columns": [ 169 + { 170 + "expression": "sandbox_id", 171 + "isExpression": false, 172 + "asc": true, 173 + "nulls": "last" 174 + }, 175 + { 176 + "expression": "path", 177 + "isExpression": false, 178 + "asc": true, 179 + "nulls": "last" 180 + } 181 + ], 182 + "isUnique": true, 183 + "concurrently": false, 184 + "method": "btree", 185 + "with": {} 186 + } 187 + }, 188 + "foreignKeys": { 189 + "sandbox_files_sandbox_id_sandboxes_id_fk": { 190 + "name": "sandbox_files_sandbox_id_sandboxes_id_fk", 191 + "tableFrom": "sandbox_files", 192 + "tableTo": "sandboxes", 193 + "columnsFrom": [ 194 + "sandbox_id" 195 + ], 196 + "columnsTo": [ 197 + "id" 198 + ], 199 + "onDelete": "no action", 200 + "onUpdate": "no action" 201 + }, 202 + "sandbox_files_file_id_files_id_fk": { 203 + "name": "sandbox_files_file_id_files_id_fk", 204 + "tableFrom": "sandbox_files", 205 + "tableTo": "files", 206 + "columnsFrom": [ 207 + "file_id" 208 + ], 209 + "columnsTo": [ 210 + "id" 211 + ], 212 + "onDelete": "no action", 213 + "onUpdate": "no action" 214 + } 215 + }, 216 + "compositePrimaryKeys": {}, 217 + "uniqueConstraints": {}, 218 + "policies": {}, 219 + "checkConstraints": {}, 220 + "isRLSEnabled": false 221 + }, 222 + "public.sandbox_secrets": { 223 + "name": "sandbox_secrets", 224 + "schema": "", 225 + "columns": { 226 + "id": { 227 + "name": "id", 228 + "type": "text", 229 + "primaryKey": true, 230 + "notNull": true, 231 + "default": "xata_id()" 232 + }, 233 + "sandbox_id": { 234 + "name": "sandbox_id", 235 + "type": "text", 236 + "primaryKey": false, 237 + "notNull": true 238 + }, 239 + "secret_id": { 240 + "name": "secret_id", 241 + "type": "text", 242 + "primaryKey": false, 243 + "notNull": true 244 + }, 245 + "name": { 246 + "name": "name", 247 + "type": "text", 248 + "primaryKey": false, 249 + "notNull": false 250 + }, 251 + "created_at": { 252 + "name": "created_at", 253 + "type": "timestamp", 254 + "primaryKey": false, 255 + "notNull": true, 256 + "default": "now()" 257 + }, 258 + "updated_at": { 259 + "name": "updated_at", 260 + "type": "timestamp", 261 + "primaryKey": false, 262 + "notNull": true, 263 + "default": "now()" 264 + } 265 + }, 266 + "indexes": { 267 + "unique_sandbox_secret": { 268 + "name": "unique_sandbox_secret", 269 + "columns": [ 270 + { 271 + "expression": "sandbox_id", 272 + "isExpression": false, 273 + "asc": true, 274 + "nulls": "last" 275 + }, 276 + { 277 + "expression": "secret_id", 278 + "isExpression": false, 279 + "asc": true, 280 + "nulls": "last" 281 + } 282 + ], 283 + "isUnique": true, 284 + "concurrently": false, 285 + "method": "btree", 286 + "with": {} 287 + }, 288 + "unique_sandbox_secret_by_name": { 289 + "name": "unique_sandbox_secret_by_name", 290 + "columns": [ 291 + { 292 + "expression": "sandbox_id", 293 + "isExpression": false, 294 + "asc": true, 295 + "nulls": "last" 296 + }, 297 + { 298 + "expression": "name", 299 + "isExpression": false, 300 + "asc": true, 301 + "nulls": "last" 302 + } 303 + ], 304 + "isUnique": true, 305 + "concurrently": false, 306 + "method": "btree", 307 + "with": {} 308 + } 309 + }, 310 + "foreignKeys": { 311 + "sandbox_secrets_sandbox_id_sandboxes_id_fk": { 312 + "name": "sandbox_secrets_sandbox_id_sandboxes_id_fk", 313 + "tableFrom": "sandbox_secrets", 314 + "tableTo": "sandboxes", 315 + "columnsFrom": [ 316 + "sandbox_id" 317 + ], 318 + "columnsTo": [ 319 + "id" 320 + ], 321 + "onDelete": "no action", 322 + "onUpdate": "no action" 323 + }, 324 + "sandbox_secrets_secret_id_secrets_id_fk": { 325 + "name": "sandbox_secrets_secret_id_secrets_id_fk", 326 + "tableFrom": "sandbox_secrets", 327 + "tableTo": "secrets", 328 + "columnsFrom": [ 329 + "secret_id" 330 + ], 331 + "columnsTo": [ 332 + "id" 333 + ], 334 + "onDelete": "no action", 335 + "onUpdate": "no action" 336 + } 337 + }, 338 + "compositePrimaryKeys": {}, 339 + "uniqueConstraints": {}, 340 + "policies": {}, 341 + "checkConstraints": {}, 342 + "isRLSEnabled": false 343 + }, 344 + "public.sandbox_variables": { 345 + "name": "sandbox_variables", 346 + "schema": "", 347 + "columns": { 348 + "id": { 349 + "name": "id", 350 + "type": "text", 351 + "primaryKey": true, 352 + "notNull": true, 353 + "default": "xata_id()" 354 + }, 355 + "sandbox_id": { 356 + "name": "sandbox_id", 357 + "type": "text", 358 + "primaryKey": false, 359 + "notNull": true 360 + }, 361 + "variable_id": { 362 + "name": "variable_id", 363 + "type": "text", 364 + "primaryKey": false, 365 + "notNull": true 366 + }, 367 + "name": { 368 + "name": "name", 369 + "type": "text", 370 + "primaryKey": false, 371 + "notNull": true 372 + }, 373 + "created_at": { 374 + "name": "created_at", 375 + "type": "timestamp", 376 + "primaryKey": false, 377 + "notNull": true, 378 + "default": "now()" 379 + }, 380 + "updated_at": { 381 + "name": "updated_at", 382 + "type": "timestamp", 383 + "primaryKey": false, 384 + "notNull": true, 385 + "default": "now()" 386 + } 387 + }, 388 + "indexes": { 389 + "unique_sandbox_variables": { 390 + "name": "unique_sandbox_variables", 391 + "columns": [ 392 + { 393 + "expression": "sandbox_id", 394 + "isExpression": false, 395 + "asc": true, 396 + "nulls": "last" 397 + }, 398 + { 399 + "expression": "variable_id", 400 + "isExpression": false, 401 + "asc": true, 402 + "nulls": "last" 403 + } 404 + ], 405 + "isUnique": true, 406 + "concurrently": false, 407 + "method": "btree", 408 + "with": {} 409 + }, 410 + "unique_sandbox_variables_by_name": { 411 + "name": "unique_sandbox_variables_by_name", 412 + "columns": [ 413 + { 414 + "expression": "sandbox_id", 415 + "isExpression": false, 416 + "asc": true, 417 + "nulls": "last" 418 + }, 419 + { 420 + "expression": "name", 421 + "isExpression": false, 422 + "asc": true, 423 + "nulls": "last" 424 + } 425 + ], 426 + "isUnique": true, 427 + "concurrently": false, 428 + "method": "btree", 429 + "with": {} 430 + } 431 + }, 432 + "foreignKeys": { 433 + "sandbox_variables_sandbox_id_sandboxes_id_fk": { 434 + "name": "sandbox_variables_sandbox_id_sandboxes_id_fk", 435 + "tableFrom": "sandbox_variables", 436 + "tableTo": "sandboxes", 437 + "columnsFrom": [ 438 + "sandbox_id" 439 + ], 440 + "columnsTo": [ 441 + "id" 442 + ], 443 + "onDelete": "no action", 444 + "onUpdate": "no action" 445 + }, 446 + "sandbox_variables_variable_id_variables_id_fk": { 447 + "name": "sandbox_variables_variable_id_variables_id_fk", 448 + "tableFrom": "sandbox_variables", 449 + "tableTo": "variables", 450 + "columnsFrom": [ 451 + "variable_id" 452 + ], 453 + "columnsTo": [ 454 + "id" 455 + ], 456 + "onDelete": "no action", 457 + "onUpdate": "no action" 458 + } 459 + }, 460 + "compositePrimaryKeys": {}, 461 + "uniqueConstraints": {}, 462 + "policies": {}, 463 + "checkConstraints": {}, 464 + "isRLSEnabled": false 465 + }, 466 + "public.sandbox_volumes": { 467 + "name": "sandbox_volumes", 468 + "schema": "", 469 + "columns": { 470 + "id": { 471 + "name": "id", 472 + "type": "text", 473 + "primaryKey": true, 474 + "notNull": true, 475 + "default": "xata_id()" 476 + }, 477 + "sandbox_id": { 478 + "name": "sandbox_id", 479 + "type": "text", 480 + "primaryKey": false, 481 + "notNull": true 482 + }, 483 + "volume_id": { 484 + "name": "volume_id", 485 + "type": "text", 486 + "primaryKey": false, 487 + "notNull": true 488 + }, 489 + "name": { 490 + "name": "name", 491 + "type": "text", 492 + "primaryKey": false, 493 + "notNull": false 494 + }, 495 + "path": { 496 + "name": "path", 497 + "type": "text", 498 + "primaryKey": false, 499 + "notNull": true 500 + }, 501 + "created_at": { 502 + "name": "created_at", 503 + "type": "timestamp", 504 + "primaryKey": false, 505 + "notNull": true, 506 + "default": "now()" 507 + }, 508 + "updated_at": { 509 + "name": "updated_at", 510 + "type": "timestamp", 511 + "primaryKey": false, 512 + "notNull": true, 513 + "default": "now()" 514 + } 515 + }, 516 + "indexes": { 517 + "unique_sandbox_volume": { 518 + "name": "unique_sandbox_volume", 519 + "columns": [ 520 + { 521 + "expression": "sandbox_id", 522 + "isExpression": false, 523 + "asc": true, 524 + "nulls": "last" 525 + }, 526 + { 527 + "expression": "volume_id", 528 + "isExpression": false, 529 + "asc": true, 530 + "nulls": "last" 531 + } 532 + ], 533 + "isUnique": true, 534 + "concurrently": false, 535 + "method": "btree", 536 + "with": {} 537 + }, 538 + "unique_sandbox_volume_path": { 539 + "name": "unique_sandbox_volume_path", 540 + "columns": [ 541 + { 542 + "expression": "sandbox_id", 543 + "isExpression": false, 544 + "asc": true, 545 + "nulls": "last" 546 + }, 547 + { 548 + "expression": "path", 549 + "isExpression": false, 550 + "asc": true, 551 + "nulls": "last" 552 + } 553 + ], 554 + "isUnique": true, 555 + "concurrently": false, 556 + "method": "btree", 557 + "with": {} 558 + } 559 + }, 560 + "foreignKeys": { 561 + "sandbox_volumes_sandbox_id_sandboxes_id_fk": { 562 + "name": "sandbox_volumes_sandbox_id_sandboxes_id_fk", 563 + "tableFrom": "sandbox_volumes", 564 + "tableTo": "sandboxes", 565 + "columnsFrom": [ 566 + "sandbox_id" 567 + ], 568 + "columnsTo": [ 569 + "id" 570 + ], 571 + "onDelete": "no action", 572 + "onUpdate": "no action" 573 + }, 574 + "sandbox_volumes_volume_id_volumes_id_fk": { 575 + "name": "sandbox_volumes_volume_id_volumes_id_fk", 576 + "tableFrom": "sandbox_volumes", 577 + "tableTo": "volumes", 578 + "columnsFrom": [ 579 + "volume_id" 580 + ], 581 + "columnsTo": [ 582 + "id" 583 + ], 584 + "onDelete": "no action", 585 + "onUpdate": "no action" 586 + } 587 + }, 588 + "compositePrimaryKeys": {}, 589 + "uniqueConstraints": {}, 590 + "policies": {}, 591 + "checkConstraints": {}, 592 + "isRLSEnabled": false 593 + }, 594 + "public.sandboxes": { 595 + "name": "sandboxes", 596 + "schema": "", 597 + "columns": { 598 + "id": { 599 + "name": "id", 600 + "type": "text", 601 + "primaryKey": true, 602 + "notNull": true, 603 + "default": "sandbox_id()" 604 + }, 605 + "base": { 606 + "name": "base", 607 + "type": "text", 608 + "primaryKey": false, 609 + "notNull": false 610 + }, 611 + "name": { 612 + "name": "name", 613 + "type": "text", 614 + "primaryKey": false, 615 + "notNull": true 616 + }, 617 + "display_name": { 618 + "name": "display_name", 619 + "type": "text", 620 + "primaryKey": false, 621 + "notNull": false 622 + }, 623 + "uri": { 624 + "name": "uri", 625 + "type": "text", 626 + "primaryKey": false, 627 + "notNull": false 628 + }, 629 + "cid": { 630 + "name": "cid", 631 + "type": "text", 632 + "primaryKey": false, 633 + "notNull": false 634 + }, 635 + "repo": { 636 + "name": "repo", 637 + "type": "text", 638 + "primaryKey": false, 639 + "notNull": false 640 + }, 641 + "provider": { 642 + "name": "provider", 643 + "type": "text", 644 + "primaryKey": false, 645 + "notNull": true, 646 + "default": "'cloudflare'" 647 + }, 648 + "description": { 649 + "name": "description", 650 + "type": "text", 651 + "primaryKey": false, 652 + "notNull": false 653 + }, 654 + "topics": { 655 + "name": "topics", 656 + "type": "text[]", 657 + "primaryKey": false, 658 + "notNull": false 659 + }, 660 + "logo": { 661 + "name": "logo", 662 + "type": "text", 663 + "primaryKey": false, 664 + "notNull": false 665 + }, 666 + "readme": { 667 + "name": "readme", 668 + "type": "text", 669 + "primaryKey": false, 670 + "notNull": false 671 + }, 672 + "public_key": { 673 + "name": "public_key", 674 + "type": "text", 675 + "primaryKey": false, 676 + "notNull": true 677 + }, 678 + "user_id": { 679 + "name": "user_id", 680 + "type": "text", 681 + "primaryKey": false, 682 + "notNull": false 683 + }, 684 + "instance_type": { 685 + "name": "instance_type", 686 + "type": "text", 687 + "primaryKey": false, 688 + "notNull": false 689 + }, 690 + "vcpus": { 691 + "name": "vcpus", 692 + "type": "integer", 693 + "primaryKey": false, 694 + "notNull": false 695 + }, 696 + "memory": { 697 + "name": "memory", 698 + "type": "integer", 699 + "primaryKey": false, 700 + "notNull": false 701 + }, 702 + "disk": { 703 + "name": "disk", 704 + "type": "integer", 705 + "primaryKey": false, 706 + "notNull": false 707 + }, 708 + "status": { 709 + "name": "status", 710 + "type": "text", 711 + "primaryKey": false, 712 + "notNull": true 713 + }, 714 + "keep_alive": { 715 + "name": "keep_alive", 716 + "type": "boolean", 717 + "primaryKey": false, 718 + "notNull": true, 719 + "default": false 720 + }, 721 + "sleep_after": { 722 + "name": "sleep_after", 723 + "type": "text", 724 + "primaryKey": false, 725 + "notNull": false 726 + }, 727 + "sandbox_id": { 728 + "name": "sandbox_id", 729 + "type": "text", 730 + "primaryKey": false, 731 + "notNull": false 732 + }, 733 + "installs": { 734 + "name": "installs", 735 + "type": "integer", 736 + "primaryKey": false, 737 + "notNull": true, 738 + "default": 0 739 + }, 740 + "started_at": { 741 + "name": "started_at", 742 + "type": "timestamp", 743 + "primaryKey": false, 744 + "notNull": false 745 + }, 746 + "created_at": { 747 + "name": "created_at", 748 + "type": "timestamp", 749 + "primaryKey": false, 750 + "notNull": true, 751 + "default": "now()" 752 + }, 753 + "updated_at": { 754 + "name": "updated_at", 755 + "type": "timestamp", 756 + "primaryKey": false, 757 + "notNull": true, 758 + "default": "now()" 759 + } 760 + }, 761 + "indexes": {}, 762 + "foreignKeys": { 763 + "sandboxes_user_id_users_id_fk": { 764 + "name": "sandboxes_user_id_users_id_fk", 765 + "tableFrom": "sandboxes", 766 + "tableTo": "users", 767 + "columnsFrom": [ 768 + "user_id" 769 + ], 770 + "columnsTo": [ 771 + "id" 772 + ], 773 + "onDelete": "no action", 774 + "onUpdate": "no action" 775 + } 776 + }, 777 + "compositePrimaryKeys": {}, 778 + "uniqueConstraints": { 779 + "sandboxes_name_unique": { 780 + "name": "sandboxes_name_unique", 781 + "nullsNotDistinct": false, 782 + "columns": [ 783 + "name" 784 + ] 785 + }, 786 + "sandboxes_uri_unique": { 787 + "name": "sandboxes_uri_unique", 788 + "nullsNotDistinct": false, 789 + "columns": [ 790 + "uri" 791 + ] 792 + }, 793 + "sandboxes_cid_unique": { 794 + "name": "sandboxes_cid_unique", 795 + "nullsNotDistinct": false, 796 + "columns": [ 797 + "cid" 798 + ] 799 + } 800 + }, 801 + "policies": {}, 802 + "checkConstraints": {}, 803 + "isRLSEnabled": false 804 + }, 805 + "public.secrets": { 806 + "name": "secrets", 807 + "schema": "", 808 + "columns": { 809 + "id": { 810 + "name": "id", 811 + "type": "text", 812 + "primaryKey": true, 813 + "notNull": true, 814 + "default": "secret_id()" 815 + }, 816 + "name": { 817 + "name": "name", 818 + "type": "text", 819 + "primaryKey": false, 820 + "notNull": true 821 + }, 822 + "value": { 823 + "name": "value", 824 + "type": "text", 825 + "primaryKey": false, 826 + "notNull": true 827 + }, 828 + "redacted": { 829 + "name": "redacted", 830 + "type": "text", 831 + "primaryKey": false, 832 + "notNull": false 833 + }, 834 + "created_at": { 835 + "name": "created_at", 836 + "type": "timestamp", 837 + "primaryKey": false, 838 + "notNull": true, 839 + "default": "now()" 840 + } 841 + }, 842 + "indexes": {}, 843 + "foreignKeys": {}, 844 + "compositePrimaryKeys": {}, 845 + "uniqueConstraints": {}, 846 + "policies": {}, 847 + "checkConstraints": {}, 848 + "isRLSEnabled": false 849 + }, 850 + "public.snapshots": { 851 + "name": "snapshots", 852 + "schema": "", 853 + "columns": { 854 + "id": { 855 + "name": "id", 856 + "type": "text", 857 + "primaryKey": true, 858 + "notNull": true, 859 + "default": "snapshot_id()" 860 + }, 861 + "slug": { 862 + "name": "slug", 863 + "type": "text", 864 + "primaryKey": false, 865 + "notNull": true 866 + }, 867 + "created_at": { 868 + "name": "created_at", 869 + "type": "timestamp", 870 + "primaryKey": false, 871 + "notNull": true, 872 + "default": "now()" 873 + } 874 + }, 875 + "indexes": {}, 876 + "foreignKeys": {}, 877 + "compositePrimaryKeys": {}, 878 + "uniqueConstraints": { 879 + "snapshots_slug_unique": { 880 + "name": "snapshots_slug_unique", 881 + "nullsNotDistinct": false, 882 + "columns": [ 883 + "slug" 884 + ] 885 + } 886 + }, 887 + "policies": {}, 888 + "checkConstraints": {}, 889 + "isRLSEnabled": false 890 + }, 891 + "public.users": { 892 + "name": "users", 893 + "schema": "", 894 + "columns": { 895 + "id": { 896 + "name": "id", 897 + "type": "text", 898 + "primaryKey": true, 899 + "notNull": true, 900 + "default": "xata_id()" 901 + }, 902 + "did": { 903 + "name": "did", 904 + "type": "text", 905 + "primaryKey": false, 906 + "notNull": true 907 + }, 908 + "display_name": { 909 + "name": "display_name", 910 + "type": "text", 911 + "primaryKey": false, 912 + "notNull": false 913 + }, 914 + "handle": { 915 + "name": "handle", 916 + "type": "text", 917 + "primaryKey": false, 918 + "notNull": true 919 + }, 920 + "avatar": { 921 + "name": "avatar", 922 + "type": "text", 923 + "primaryKey": false, 924 + "notNull": false 925 + }, 926 + "created_at": { 927 + "name": "created_at", 928 + "type": "timestamp", 929 + "primaryKey": false, 930 + "notNull": true, 931 + "default": "now()" 932 + }, 933 + "updated_at": { 934 + "name": "updated_at", 935 + "type": "timestamp", 936 + "primaryKey": false, 937 + "notNull": true, 938 + "default": "now()" 939 + } 940 + }, 941 + "indexes": {}, 942 + "foreignKeys": {}, 943 + "compositePrimaryKeys": {}, 944 + "uniqueConstraints": { 945 + "users_did_unique": { 946 + "name": "users_did_unique", 947 + "nullsNotDistinct": false, 948 + "columns": [ 949 + "did" 950 + ] 951 + }, 952 + "users_handle_unique": { 953 + "name": "users_handle_unique", 954 + "nullsNotDistinct": false, 955 + "columns": [ 956 + "handle" 957 + ] 958 + } 959 + }, 960 + "policies": {}, 961 + "checkConstraints": {}, 962 + "isRLSEnabled": false 963 + }, 964 + "public.variables": { 965 + "name": "variables", 966 + "schema": "", 967 + "columns": { 968 + "id": { 969 + "name": "id", 970 + "type": "text", 971 + "primaryKey": true, 972 + "notNull": true, 973 + "default": "variable_id()" 974 + }, 975 + "name": { 976 + "name": "name", 977 + "type": "text", 978 + "primaryKey": false, 979 + "notNull": true 980 + }, 981 + "value": { 982 + "name": "value", 983 + "type": "text", 984 + "primaryKey": false, 985 + "notNull": true 986 + }, 987 + "created_at": { 988 + "name": "created_at", 989 + "type": "timestamp", 990 + "primaryKey": false, 991 + "notNull": true, 992 + "default": "now()" 993 + }, 994 + "updated_at": { 995 + "name": "updated_at", 996 + "type": "timestamp", 997 + "primaryKey": false, 998 + "notNull": true, 999 + "default": "now()" 1000 + } 1001 + }, 1002 + "indexes": {}, 1003 + "foreignKeys": {}, 1004 + "compositePrimaryKeys": {}, 1005 + "uniqueConstraints": {}, 1006 + "policies": {}, 1007 + "checkConstraints": {}, 1008 + "isRLSEnabled": false 1009 + }, 1010 + "public.volumes": { 1011 + "name": "volumes", 1012 + "schema": "", 1013 + "columns": { 1014 + "id": { 1015 + "name": "id", 1016 + "type": "text", 1017 + "primaryKey": true, 1018 + "notNull": true, 1019 + "default": "volume_id()" 1020 + }, 1021 + "slug": { 1022 + "name": "slug", 1023 + "type": "text", 1024 + "primaryKey": false, 1025 + "notNull": true 1026 + }, 1027 + "size": { 1028 + "name": "size", 1029 + "type": "integer", 1030 + "primaryKey": false, 1031 + "notNull": true 1032 + }, 1033 + "size_unit": { 1034 + "name": "size_unit", 1035 + "type": "text", 1036 + "primaryKey": false, 1037 + "notNull": true 1038 + }, 1039 + "created_at": { 1040 + "name": "created_at", 1041 + "type": "timestamp", 1042 + "primaryKey": false, 1043 + "notNull": true, 1044 + "default": "now()" 1045 + }, 1046 + "updated_at": { 1047 + "name": "updated_at", 1048 + "type": "timestamp", 1049 + "primaryKey": false, 1050 + "notNull": true, 1051 + "default": "now()" 1052 + } 1053 + }, 1054 + "indexes": {}, 1055 + "foreignKeys": {}, 1056 + "compositePrimaryKeys": {}, 1057 + "uniqueConstraints": { 1058 + "volumes_slug_unique": { 1059 + "name": "volumes_slug_unique", 1060 + "nullsNotDistinct": false, 1061 + "columns": [ 1062 + "slug" 1063 + ] 1064 + } 1065 + }, 1066 + "policies": {}, 1067 + "checkConstraints": {}, 1068 + "isRLSEnabled": false 1069 + }, 1070 + "public.integrations": { 1071 + "name": "integrations", 1072 + "schema": "", 1073 + "columns": { 1074 + "id": { 1075 + "name": "id", 1076 + "type": "text", 1077 + "primaryKey": true, 1078 + "notNull": true, 1079 + "default": "xata_id()" 1080 + }, 1081 + "sandbox_id": { 1082 + "name": "sandbox_id", 1083 + "type": "text", 1084 + "primaryKey": false, 1085 + "notNull": true 1086 + }, 1087 + "name": { 1088 + "name": "name", 1089 + "type": "text", 1090 + "primaryKey": false, 1091 + "notNull": true 1092 + }, 1093 + "description": { 1094 + "name": "description", 1095 + "type": "text", 1096 + "primaryKey": false, 1097 + "notNull": false 1098 + }, 1099 + "webhook_url": { 1100 + "name": "webhook_url", 1101 + "type": "text", 1102 + "primaryKey": false, 1103 + "notNull": true 1104 + }, 1105 + "created_at": { 1106 + "name": "created_at", 1107 + "type": "timestamp", 1108 + "primaryKey": false, 1109 + "notNull": true, 1110 + "default": "now()" 1111 + } 1112 + }, 1113 + "indexes": { 1114 + "unique_sandbox_integration": { 1115 + "name": "unique_sandbox_integration", 1116 + "columns": [ 1117 + { 1118 + "expression": "sandbox_id", 1119 + "isExpression": false, 1120 + "asc": true, 1121 + "nulls": "last" 1122 + }, 1123 + { 1124 + "expression": "name", 1125 + "isExpression": false, 1126 + "asc": true, 1127 + "nulls": "last" 1128 + } 1129 + ], 1130 + "isUnique": true, 1131 + "concurrently": false, 1132 + "method": "btree", 1133 + "with": {} 1134 + } 1135 + }, 1136 + "foreignKeys": { 1137 + "integrations_sandbox_id_sandboxes_id_fk": { 1138 + "name": "integrations_sandbox_id_sandboxes_id_fk", 1139 + "tableFrom": "integrations", 1140 + "tableTo": "sandboxes", 1141 + "columnsFrom": [ 1142 + "sandbox_id" 1143 + ], 1144 + "columnsTo": [ 1145 + "id" 1146 + ], 1147 + "onDelete": "no action", 1148 + "onUpdate": "no action" 1149 + } 1150 + }, 1151 + "compositePrimaryKeys": {}, 1152 + "uniqueConstraints": {}, 1153 + "policies": {}, 1154 + "checkConstraints": {}, 1155 + "isRLSEnabled": false 1156 + }, 1157 + "public.ssh_keys": { 1158 + "name": "ssh_keys", 1159 + "schema": "", 1160 + "columns": { 1161 + "id": { 1162 + "name": "id", 1163 + "type": "text", 1164 + "primaryKey": true, 1165 + "notNull": true, 1166 + "default": "xata_id()" 1167 + }, 1168 + "sandbox_id": { 1169 + "name": "sandbox_id", 1170 + "type": "text", 1171 + "primaryKey": false, 1172 + "notNull": true 1173 + }, 1174 + "public_key": { 1175 + "name": "public_key", 1176 + "type": "text", 1177 + "primaryKey": false, 1178 + "notNull": true 1179 + }, 1180 + "private_key": { 1181 + "name": "private_key", 1182 + "type": "text", 1183 + "primaryKey": false, 1184 + "notNull": true 1185 + }, 1186 + "redacted": { 1187 + "name": "redacted", 1188 + "type": "text", 1189 + "primaryKey": false, 1190 + "notNull": false 1191 + }, 1192 + "created_at": { 1193 + "name": "created_at", 1194 + "type": "timestamp", 1195 + "primaryKey": false, 1196 + "notNull": true, 1197 + "default": "now()" 1198 + } 1199 + }, 1200 + "indexes": { 1201 + "unique_sandbox_ssh_key": { 1202 + "name": "unique_sandbox_ssh_key", 1203 + "columns": [ 1204 + { 1205 + "expression": "public_key", 1206 + "isExpression": false, 1207 + "asc": true, 1208 + "nulls": "last" 1209 + }, 1210 + { 1211 + "expression": "sandbox_id", 1212 + "isExpression": false, 1213 + "asc": true, 1214 + "nulls": "last" 1215 + } 1216 + ], 1217 + "isUnique": true, 1218 + "concurrently": false, 1219 + "method": "btree", 1220 + "with": {} 1221 + } 1222 + }, 1223 + "foreignKeys": { 1224 + "ssh_keys_sandbox_id_sandboxes_id_fk": { 1225 + "name": "ssh_keys_sandbox_id_sandboxes_id_fk", 1226 + "tableFrom": "ssh_keys", 1227 + "tableTo": "sandboxes", 1228 + "columnsFrom": [ 1229 + "sandbox_id" 1230 + ], 1231 + "columnsTo": [ 1232 + "id" 1233 + ], 1234 + "onDelete": "no action", 1235 + "onUpdate": "no action" 1236 + } 1237 + }, 1238 + "compositePrimaryKeys": {}, 1239 + "uniqueConstraints": {}, 1240 + "policies": {}, 1241 + "checkConstraints": {}, 1242 + "isRLSEnabled": false 1243 + }, 1244 + "public.tailscale_tokens": { 1245 + "name": "tailscale_tokens", 1246 + "schema": "", 1247 + "columns": { 1248 + "id": { 1249 + "name": "id", 1250 + "type": "text", 1251 + "primaryKey": true, 1252 + "notNull": true, 1253 + "default": "xata_id()" 1254 + }, 1255 + "sandbox_id": { 1256 + "name": "sandbox_id", 1257 + "type": "text", 1258 + "primaryKey": false, 1259 + "notNull": false 1260 + }, 1261 + "tokens": { 1262 + "name": "tokens", 1263 + "type": "text", 1264 + "primaryKey": false, 1265 + "notNull": true 1266 + }, 1267 + "redacted": { 1268 + "name": "redacted", 1269 + "type": "text", 1270 + "primaryKey": false, 1271 + "notNull": true 1272 + }, 1273 + "created_at": { 1274 + "name": "created_at", 1275 + "type": "timestamp", 1276 + "primaryKey": false, 1277 + "notNull": true, 1278 + "default": "now()" 1279 + } 1280 + }, 1281 + "indexes": {}, 1282 + "foreignKeys": { 1283 + "tailscale_tokens_sandbox_id_sandboxes_id_fk": { 1284 + "name": "tailscale_tokens_sandbox_id_sandboxes_id_fk", 1285 + "tableFrom": "tailscale_tokens", 1286 + "tableTo": "sandboxes", 1287 + "columnsFrom": [ 1288 + "sandbox_id" 1289 + ], 1290 + "columnsTo": [ 1291 + "id" 1292 + ], 1293 + "onDelete": "no action", 1294 + "onUpdate": "no action" 1295 + } 1296 + }, 1297 + "compositePrimaryKeys": {}, 1298 + "uniqueConstraints": {}, 1299 + "policies": {}, 1300 + "checkConstraints": {}, 1301 + "isRLSEnabled": false 1302 + } 1303 + }, 1304 + "enums": {}, 1305 + "schemas": {}, 1306 + "sequences": {}, 1307 + "roles": {}, 1308 + "policies": {}, 1309 + "views": {}, 1310 + "_meta": { 1311 + "columns": {}, 1312 + "schemas": {}, 1313 + "tables": {} 1314 + } 1315 + }
+1315
apps/cf-sandbox/drizzle/meta/0025_snapshot.json
··· 1 + { 2 + "id": "7c2213ab-de38-4110-a874-cf45e0108dcf", 3 + "prevId": "fd9f2cf3-2b96-4f64-a06a-1984ed7647fd", 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": "variable_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": "xata_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": { 146 + "name": "unique_sandbox_file", 147 + "columns": [ 148 + { 149 + "expression": "sandbox_id", 150 + "isExpression": false, 151 + "asc": true, 152 + "nulls": "last" 153 + }, 154 + { 155 + "expression": "file_id", 156 + "isExpression": false, 157 + "asc": true, 158 + "nulls": "last" 159 + } 160 + ], 161 + "isUnique": true, 162 + "concurrently": false, 163 + "method": "btree", 164 + "with": {} 165 + }, 166 + "unique_sandbox_file_path": { 167 + "name": "unique_sandbox_file_path", 168 + "columns": [ 169 + { 170 + "expression": "sandbox_id", 171 + "isExpression": false, 172 + "asc": true, 173 + "nulls": "last" 174 + }, 175 + { 176 + "expression": "path", 177 + "isExpression": false, 178 + "asc": true, 179 + "nulls": "last" 180 + } 181 + ], 182 + "isUnique": true, 183 + "concurrently": false, 184 + "method": "btree", 185 + "with": {} 186 + } 187 + }, 188 + "foreignKeys": { 189 + "sandbox_files_sandbox_id_sandboxes_id_fk": { 190 + "name": "sandbox_files_sandbox_id_sandboxes_id_fk", 191 + "tableFrom": "sandbox_files", 192 + "tableTo": "sandboxes", 193 + "columnsFrom": [ 194 + "sandbox_id" 195 + ], 196 + "columnsTo": [ 197 + "id" 198 + ], 199 + "onDelete": "no action", 200 + "onUpdate": "no action" 201 + }, 202 + "sandbox_files_file_id_files_id_fk": { 203 + "name": "sandbox_files_file_id_files_id_fk", 204 + "tableFrom": "sandbox_files", 205 + "tableTo": "files", 206 + "columnsFrom": [ 207 + "file_id" 208 + ], 209 + "columnsTo": [ 210 + "id" 211 + ], 212 + "onDelete": "no action", 213 + "onUpdate": "no action" 214 + } 215 + }, 216 + "compositePrimaryKeys": {}, 217 + "uniqueConstraints": {}, 218 + "policies": {}, 219 + "checkConstraints": {}, 220 + "isRLSEnabled": false 221 + }, 222 + "public.sandbox_secrets": { 223 + "name": "sandbox_secrets", 224 + "schema": "", 225 + "columns": { 226 + "id": { 227 + "name": "id", 228 + "type": "text", 229 + "primaryKey": true, 230 + "notNull": true, 231 + "default": "xata_id()" 232 + }, 233 + "sandbox_id": { 234 + "name": "sandbox_id", 235 + "type": "text", 236 + "primaryKey": false, 237 + "notNull": true 238 + }, 239 + "secret_id": { 240 + "name": "secret_id", 241 + "type": "text", 242 + "primaryKey": false, 243 + "notNull": true 244 + }, 245 + "name": { 246 + "name": "name", 247 + "type": "text", 248 + "primaryKey": false, 249 + "notNull": false 250 + }, 251 + "created_at": { 252 + "name": "created_at", 253 + "type": "timestamp", 254 + "primaryKey": false, 255 + "notNull": true, 256 + "default": "now()" 257 + }, 258 + "updated_at": { 259 + "name": "updated_at", 260 + "type": "timestamp", 261 + "primaryKey": false, 262 + "notNull": true, 263 + "default": "now()" 264 + } 265 + }, 266 + "indexes": { 267 + "unique_sandbox_secret": { 268 + "name": "unique_sandbox_secret", 269 + "columns": [ 270 + { 271 + "expression": "sandbox_id", 272 + "isExpression": false, 273 + "asc": true, 274 + "nulls": "last" 275 + }, 276 + { 277 + "expression": "secret_id", 278 + "isExpression": false, 279 + "asc": true, 280 + "nulls": "last" 281 + } 282 + ], 283 + "isUnique": true, 284 + "concurrently": false, 285 + "method": "btree", 286 + "with": {} 287 + }, 288 + "unique_sandbox_secret_by_name": { 289 + "name": "unique_sandbox_secret_by_name", 290 + "columns": [ 291 + { 292 + "expression": "sandbox_id", 293 + "isExpression": false, 294 + "asc": true, 295 + "nulls": "last" 296 + }, 297 + { 298 + "expression": "name", 299 + "isExpression": false, 300 + "asc": true, 301 + "nulls": "last" 302 + } 303 + ], 304 + "isUnique": true, 305 + "concurrently": false, 306 + "method": "btree", 307 + "with": {} 308 + } 309 + }, 310 + "foreignKeys": { 311 + "sandbox_secrets_sandbox_id_sandboxes_id_fk": { 312 + "name": "sandbox_secrets_sandbox_id_sandboxes_id_fk", 313 + "tableFrom": "sandbox_secrets", 314 + "tableTo": "sandboxes", 315 + "columnsFrom": [ 316 + "sandbox_id" 317 + ], 318 + "columnsTo": [ 319 + "id" 320 + ], 321 + "onDelete": "no action", 322 + "onUpdate": "no action" 323 + }, 324 + "sandbox_secrets_secret_id_secrets_id_fk": { 325 + "name": "sandbox_secrets_secret_id_secrets_id_fk", 326 + "tableFrom": "sandbox_secrets", 327 + "tableTo": "secrets", 328 + "columnsFrom": [ 329 + "secret_id" 330 + ], 331 + "columnsTo": [ 332 + "id" 333 + ], 334 + "onDelete": "no action", 335 + "onUpdate": "no action" 336 + } 337 + }, 338 + "compositePrimaryKeys": {}, 339 + "uniqueConstraints": {}, 340 + "policies": {}, 341 + "checkConstraints": {}, 342 + "isRLSEnabled": false 343 + }, 344 + "public.sandbox_variables": { 345 + "name": "sandbox_variables", 346 + "schema": "", 347 + "columns": { 348 + "id": { 349 + "name": "id", 350 + "type": "text", 351 + "primaryKey": true, 352 + "notNull": true, 353 + "default": "xata_id()" 354 + }, 355 + "sandbox_id": { 356 + "name": "sandbox_id", 357 + "type": "text", 358 + "primaryKey": false, 359 + "notNull": true 360 + }, 361 + "variable_id": { 362 + "name": "variable_id", 363 + "type": "text", 364 + "primaryKey": false, 365 + "notNull": true 366 + }, 367 + "name": { 368 + "name": "name", 369 + "type": "text", 370 + "primaryKey": false, 371 + "notNull": true 372 + }, 373 + "created_at": { 374 + "name": "created_at", 375 + "type": "timestamp", 376 + "primaryKey": false, 377 + "notNull": true, 378 + "default": "now()" 379 + }, 380 + "updated_at": { 381 + "name": "updated_at", 382 + "type": "timestamp", 383 + "primaryKey": false, 384 + "notNull": true, 385 + "default": "now()" 386 + } 387 + }, 388 + "indexes": { 389 + "unique_sandbox_variables": { 390 + "name": "unique_sandbox_variables", 391 + "columns": [ 392 + { 393 + "expression": "sandbox_id", 394 + "isExpression": false, 395 + "asc": true, 396 + "nulls": "last" 397 + }, 398 + { 399 + "expression": "variable_id", 400 + "isExpression": false, 401 + "asc": true, 402 + "nulls": "last" 403 + } 404 + ], 405 + "isUnique": true, 406 + "concurrently": false, 407 + "method": "btree", 408 + "with": {} 409 + }, 410 + "unique_sandbox_variables_by_name": { 411 + "name": "unique_sandbox_variables_by_name", 412 + "columns": [ 413 + { 414 + "expression": "sandbox_id", 415 + "isExpression": false, 416 + "asc": true, 417 + "nulls": "last" 418 + }, 419 + { 420 + "expression": "name", 421 + "isExpression": false, 422 + "asc": true, 423 + "nulls": "last" 424 + } 425 + ], 426 + "isUnique": true, 427 + "concurrently": false, 428 + "method": "btree", 429 + "with": {} 430 + } 431 + }, 432 + "foreignKeys": { 433 + "sandbox_variables_sandbox_id_sandboxes_id_fk": { 434 + "name": "sandbox_variables_sandbox_id_sandboxes_id_fk", 435 + "tableFrom": "sandbox_variables", 436 + "tableTo": "sandboxes", 437 + "columnsFrom": [ 438 + "sandbox_id" 439 + ], 440 + "columnsTo": [ 441 + "id" 442 + ], 443 + "onDelete": "no action", 444 + "onUpdate": "no action" 445 + }, 446 + "sandbox_variables_variable_id_variables_id_fk": { 447 + "name": "sandbox_variables_variable_id_variables_id_fk", 448 + "tableFrom": "sandbox_variables", 449 + "tableTo": "variables", 450 + "columnsFrom": [ 451 + "variable_id" 452 + ], 453 + "columnsTo": [ 454 + "id" 455 + ], 456 + "onDelete": "no action", 457 + "onUpdate": "no action" 458 + } 459 + }, 460 + "compositePrimaryKeys": {}, 461 + "uniqueConstraints": {}, 462 + "policies": {}, 463 + "checkConstraints": {}, 464 + "isRLSEnabled": false 465 + }, 466 + "public.sandbox_volumes": { 467 + "name": "sandbox_volumes", 468 + "schema": "", 469 + "columns": { 470 + "id": { 471 + "name": "id", 472 + "type": "text", 473 + "primaryKey": true, 474 + "notNull": true, 475 + "default": "xata_id()" 476 + }, 477 + "sandbox_id": { 478 + "name": "sandbox_id", 479 + "type": "text", 480 + "primaryKey": false, 481 + "notNull": true 482 + }, 483 + "volume_id": { 484 + "name": "volume_id", 485 + "type": "text", 486 + "primaryKey": false, 487 + "notNull": true 488 + }, 489 + "name": { 490 + "name": "name", 491 + "type": "text", 492 + "primaryKey": false, 493 + "notNull": false 494 + }, 495 + "path": { 496 + "name": "path", 497 + "type": "text", 498 + "primaryKey": false, 499 + "notNull": true 500 + }, 501 + "created_at": { 502 + "name": "created_at", 503 + "type": "timestamp", 504 + "primaryKey": false, 505 + "notNull": true, 506 + "default": "now()" 507 + }, 508 + "updated_at": { 509 + "name": "updated_at", 510 + "type": "timestamp", 511 + "primaryKey": false, 512 + "notNull": true, 513 + "default": "now()" 514 + } 515 + }, 516 + "indexes": { 517 + "unique_sandbox_volume": { 518 + "name": "unique_sandbox_volume", 519 + "columns": [ 520 + { 521 + "expression": "sandbox_id", 522 + "isExpression": false, 523 + "asc": true, 524 + "nulls": "last" 525 + }, 526 + { 527 + "expression": "volume_id", 528 + "isExpression": false, 529 + "asc": true, 530 + "nulls": "last" 531 + } 532 + ], 533 + "isUnique": true, 534 + "concurrently": false, 535 + "method": "btree", 536 + "with": {} 537 + }, 538 + "unique_sandbox_volume_path": { 539 + "name": "unique_sandbox_volume_path", 540 + "columns": [ 541 + { 542 + "expression": "sandbox_id", 543 + "isExpression": false, 544 + "asc": true, 545 + "nulls": "last" 546 + }, 547 + { 548 + "expression": "path", 549 + "isExpression": false, 550 + "asc": true, 551 + "nulls": "last" 552 + } 553 + ], 554 + "isUnique": true, 555 + "concurrently": false, 556 + "method": "btree", 557 + "with": {} 558 + } 559 + }, 560 + "foreignKeys": { 561 + "sandbox_volumes_sandbox_id_sandboxes_id_fk": { 562 + "name": "sandbox_volumes_sandbox_id_sandboxes_id_fk", 563 + "tableFrom": "sandbox_volumes", 564 + "tableTo": "sandboxes", 565 + "columnsFrom": [ 566 + "sandbox_id" 567 + ], 568 + "columnsTo": [ 569 + "id" 570 + ], 571 + "onDelete": "no action", 572 + "onUpdate": "no action" 573 + }, 574 + "sandbox_volumes_volume_id_volumes_id_fk": { 575 + "name": "sandbox_volumes_volume_id_volumes_id_fk", 576 + "tableFrom": "sandbox_volumes", 577 + "tableTo": "volumes", 578 + "columnsFrom": [ 579 + "volume_id" 580 + ], 581 + "columnsTo": [ 582 + "id" 583 + ], 584 + "onDelete": "no action", 585 + "onUpdate": "no action" 586 + } 587 + }, 588 + "compositePrimaryKeys": {}, 589 + "uniqueConstraints": {}, 590 + "policies": {}, 591 + "checkConstraints": {}, 592 + "isRLSEnabled": false 593 + }, 594 + "public.sandboxes": { 595 + "name": "sandboxes", 596 + "schema": "", 597 + "columns": { 598 + "id": { 599 + "name": "id", 600 + "type": "text", 601 + "primaryKey": true, 602 + "notNull": true, 603 + "default": "sandbox_id()" 604 + }, 605 + "base": { 606 + "name": "base", 607 + "type": "text", 608 + "primaryKey": false, 609 + "notNull": false 610 + }, 611 + "name": { 612 + "name": "name", 613 + "type": "text", 614 + "primaryKey": false, 615 + "notNull": true 616 + }, 617 + "display_name": { 618 + "name": "display_name", 619 + "type": "text", 620 + "primaryKey": false, 621 + "notNull": false 622 + }, 623 + "uri": { 624 + "name": "uri", 625 + "type": "text", 626 + "primaryKey": false, 627 + "notNull": false 628 + }, 629 + "cid": { 630 + "name": "cid", 631 + "type": "text", 632 + "primaryKey": false, 633 + "notNull": false 634 + }, 635 + "repo": { 636 + "name": "repo", 637 + "type": "text", 638 + "primaryKey": false, 639 + "notNull": false 640 + }, 641 + "provider": { 642 + "name": "provider", 643 + "type": "text", 644 + "primaryKey": false, 645 + "notNull": true, 646 + "default": "'cloudflare'" 647 + }, 648 + "description": { 649 + "name": "description", 650 + "type": "text", 651 + "primaryKey": false, 652 + "notNull": false 653 + }, 654 + "topics": { 655 + "name": "topics", 656 + "type": "text[]", 657 + "primaryKey": false, 658 + "notNull": false 659 + }, 660 + "logo": { 661 + "name": "logo", 662 + "type": "text", 663 + "primaryKey": false, 664 + "notNull": false 665 + }, 666 + "readme": { 667 + "name": "readme", 668 + "type": "text", 669 + "primaryKey": false, 670 + "notNull": false 671 + }, 672 + "public_key": { 673 + "name": "public_key", 674 + "type": "text", 675 + "primaryKey": false, 676 + "notNull": true 677 + }, 678 + "user_id": { 679 + "name": "user_id", 680 + "type": "text", 681 + "primaryKey": false, 682 + "notNull": false 683 + }, 684 + "instance_type": { 685 + "name": "instance_type", 686 + "type": "text", 687 + "primaryKey": false, 688 + "notNull": false 689 + }, 690 + "vcpus": { 691 + "name": "vcpus", 692 + "type": "integer", 693 + "primaryKey": false, 694 + "notNull": false 695 + }, 696 + "memory": { 697 + "name": "memory", 698 + "type": "integer", 699 + "primaryKey": false, 700 + "notNull": false 701 + }, 702 + "disk": { 703 + "name": "disk", 704 + "type": "integer", 705 + "primaryKey": false, 706 + "notNull": false 707 + }, 708 + "status": { 709 + "name": "status", 710 + "type": "text", 711 + "primaryKey": false, 712 + "notNull": true 713 + }, 714 + "keep_alive": { 715 + "name": "keep_alive", 716 + "type": "boolean", 717 + "primaryKey": false, 718 + "notNull": true, 719 + "default": false 720 + }, 721 + "sleep_after": { 722 + "name": "sleep_after", 723 + "type": "text", 724 + "primaryKey": false, 725 + "notNull": false 726 + }, 727 + "sandbox_id": { 728 + "name": "sandbox_id", 729 + "type": "text", 730 + "primaryKey": false, 731 + "notNull": false 732 + }, 733 + "installs": { 734 + "name": "installs", 735 + "type": "integer", 736 + "primaryKey": false, 737 + "notNull": true, 738 + "default": 0 739 + }, 740 + "started_at": { 741 + "name": "started_at", 742 + "type": "timestamp", 743 + "primaryKey": false, 744 + "notNull": false 745 + }, 746 + "created_at": { 747 + "name": "created_at", 748 + "type": "timestamp", 749 + "primaryKey": false, 750 + "notNull": true, 751 + "default": "now()" 752 + }, 753 + "updated_at": { 754 + "name": "updated_at", 755 + "type": "timestamp", 756 + "primaryKey": false, 757 + "notNull": true, 758 + "default": "now()" 759 + } 760 + }, 761 + "indexes": {}, 762 + "foreignKeys": { 763 + "sandboxes_user_id_users_id_fk": { 764 + "name": "sandboxes_user_id_users_id_fk", 765 + "tableFrom": "sandboxes", 766 + "tableTo": "users", 767 + "columnsFrom": [ 768 + "user_id" 769 + ], 770 + "columnsTo": [ 771 + "id" 772 + ], 773 + "onDelete": "no action", 774 + "onUpdate": "no action" 775 + } 776 + }, 777 + "compositePrimaryKeys": {}, 778 + "uniqueConstraints": { 779 + "sandboxes_name_unique": { 780 + "name": "sandboxes_name_unique", 781 + "nullsNotDistinct": false, 782 + "columns": [ 783 + "name" 784 + ] 785 + }, 786 + "sandboxes_uri_unique": { 787 + "name": "sandboxes_uri_unique", 788 + "nullsNotDistinct": false, 789 + "columns": [ 790 + "uri" 791 + ] 792 + }, 793 + "sandboxes_cid_unique": { 794 + "name": "sandboxes_cid_unique", 795 + "nullsNotDistinct": false, 796 + "columns": [ 797 + "cid" 798 + ] 799 + } 800 + }, 801 + "policies": {}, 802 + "checkConstraints": {}, 803 + "isRLSEnabled": false 804 + }, 805 + "public.secrets": { 806 + "name": "secrets", 807 + "schema": "", 808 + "columns": { 809 + "id": { 810 + "name": "id", 811 + "type": "text", 812 + "primaryKey": true, 813 + "notNull": true, 814 + "default": "secret_id()" 815 + }, 816 + "name": { 817 + "name": "name", 818 + "type": "text", 819 + "primaryKey": false, 820 + "notNull": true 821 + }, 822 + "value": { 823 + "name": "value", 824 + "type": "text", 825 + "primaryKey": false, 826 + "notNull": true 827 + }, 828 + "redacted": { 829 + "name": "redacted", 830 + "type": "text", 831 + "primaryKey": false, 832 + "notNull": false 833 + }, 834 + "created_at": { 835 + "name": "created_at", 836 + "type": "timestamp", 837 + "primaryKey": false, 838 + "notNull": true, 839 + "default": "now()" 840 + } 841 + }, 842 + "indexes": {}, 843 + "foreignKeys": {}, 844 + "compositePrimaryKeys": {}, 845 + "uniqueConstraints": {}, 846 + "policies": {}, 847 + "checkConstraints": {}, 848 + "isRLSEnabled": false 849 + }, 850 + "public.snapshots": { 851 + "name": "snapshots", 852 + "schema": "", 853 + "columns": { 854 + "id": { 855 + "name": "id", 856 + "type": "text", 857 + "primaryKey": true, 858 + "notNull": true, 859 + "default": "snapshot_id()" 860 + }, 861 + "slug": { 862 + "name": "slug", 863 + "type": "text", 864 + "primaryKey": false, 865 + "notNull": true 866 + }, 867 + "created_at": { 868 + "name": "created_at", 869 + "type": "timestamp", 870 + "primaryKey": false, 871 + "notNull": true, 872 + "default": "now()" 873 + } 874 + }, 875 + "indexes": {}, 876 + "foreignKeys": {}, 877 + "compositePrimaryKeys": {}, 878 + "uniqueConstraints": { 879 + "snapshots_slug_unique": { 880 + "name": "snapshots_slug_unique", 881 + "nullsNotDistinct": false, 882 + "columns": [ 883 + "slug" 884 + ] 885 + } 886 + }, 887 + "policies": {}, 888 + "checkConstraints": {}, 889 + "isRLSEnabled": false 890 + }, 891 + "public.ssh_keys": { 892 + "name": "ssh_keys", 893 + "schema": "", 894 + "columns": { 895 + "id": { 896 + "name": "id", 897 + "type": "text", 898 + "primaryKey": true, 899 + "notNull": true, 900 + "default": "xata_id()" 901 + }, 902 + "sandbox_id": { 903 + "name": "sandbox_id", 904 + "type": "text", 905 + "primaryKey": false, 906 + "notNull": true 907 + }, 908 + "public_key": { 909 + "name": "public_key", 910 + "type": "text", 911 + "primaryKey": false, 912 + "notNull": true 913 + }, 914 + "private_key": { 915 + "name": "private_key", 916 + "type": "text", 917 + "primaryKey": false, 918 + "notNull": true 919 + }, 920 + "redacted": { 921 + "name": "redacted", 922 + "type": "text", 923 + "primaryKey": false, 924 + "notNull": false 925 + }, 926 + "created_at": { 927 + "name": "created_at", 928 + "type": "timestamp", 929 + "primaryKey": false, 930 + "notNull": true, 931 + "default": "now()" 932 + } 933 + }, 934 + "indexes": { 935 + "unique_sandbox_ssh_key": { 936 + "name": "unique_sandbox_ssh_key", 937 + "columns": [ 938 + { 939 + "expression": "public_key", 940 + "isExpression": false, 941 + "asc": true, 942 + "nulls": "last" 943 + }, 944 + { 945 + "expression": "sandbox_id", 946 + "isExpression": false, 947 + "asc": true, 948 + "nulls": "last" 949 + } 950 + ], 951 + "isUnique": true, 952 + "concurrently": false, 953 + "method": "btree", 954 + "with": {} 955 + } 956 + }, 957 + "foreignKeys": { 958 + "ssh_keys_sandbox_id_sandboxes_id_fk": { 959 + "name": "ssh_keys_sandbox_id_sandboxes_id_fk", 960 + "tableFrom": "ssh_keys", 961 + "tableTo": "sandboxes", 962 + "columnsFrom": [ 963 + "sandbox_id" 964 + ], 965 + "columnsTo": [ 966 + "id" 967 + ], 968 + "onDelete": "no action", 969 + "onUpdate": "no action" 970 + } 971 + }, 972 + "compositePrimaryKeys": {}, 973 + "uniqueConstraints": {}, 974 + "policies": {}, 975 + "checkConstraints": {}, 976 + "isRLSEnabled": false 977 + }, 978 + "public.tailscale_auth_keys": { 979 + "name": "tailscale_auth_keys", 980 + "schema": "", 981 + "columns": { 982 + "id": { 983 + "name": "id", 984 + "type": "text", 985 + "primaryKey": true, 986 + "notNull": true, 987 + "default": "xata_id()" 988 + }, 989 + "sandbox_id": { 990 + "name": "sandbox_id", 991 + "type": "text", 992 + "primaryKey": false, 993 + "notNull": true 994 + }, 995 + "auth_key": { 996 + "name": "auth_key", 997 + "type": "text", 998 + "primaryKey": false, 999 + "notNull": true 1000 + }, 1001 + "redacted": { 1002 + "name": "redacted", 1003 + "type": "text", 1004 + "primaryKey": false, 1005 + "notNull": true 1006 + }, 1007 + "created_at": { 1008 + "name": "created_at", 1009 + "type": "timestamp", 1010 + "primaryKey": false, 1011 + "notNull": true, 1012 + "default": "now()" 1013 + } 1014 + }, 1015 + "indexes": {}, 1016 + "foreignKeys": { 1017 + "tailscale_auth_keys_sandbox_id_sandboxes_id_fk": { 1018 + "name": "tailscale_auth_keys_sandbox_id_sandboxes_id_fk", 1019 + "tableFrom": "tailscale_auth_keys", 1020 + "tableTo": "sandboxes", 1021 + "columnsFrom": [ 1022 + "sandbox_id" 1023 + ], 1024 + "columnsTo": [ 1025 + "id" 1026 + ], 1027 + "onDelete": "no action", 1028 + "onUpdate": "no action" 1029 + } 1030 + }, 1031 + "compositePrimaryKeys": {}, 1032 + "uniqueConstraints": {}, 1033 + "policies": {}, 1034 + "checkConstraints": {}, 1035 + "isRLSEnabled": false 1036 + }, 1037 + "public.users": { 1038 + "name": "users", 1039 + "schema": "", 1040 + "columns": { 1041 + "id": { 1042 + "name": "id", 1043 + "type": "text", 1044 + "primaryKey": true, 1045 + "notNull": true, 1046 + "default": "xata_id()" 1047 + }, 1048 + "did": { 1049 + "name": "did", 1050 + "type": "text", 1051 + "primaryKey": false, 1052 + "notNull": true 1053 + }, 1054 + "display_name": { 1055 + "name": "display_name", 1056 + "type": "text", 1057 + "primaryKey": false, 1058 + "notNull": false 1059 + }, 1060 + "handle": { 1061 + "name": "handle", 1062 + "type": "text", 1063 + "primaryKey": false, 1064 + "notNull": true 1065 + }, 1066 + "avatar": { 1067 + "name": "avatar", 1068 + "type": "text", 1069 + "primaryKey": false, 1070 + "notNull": false 1071 + }, 1072 + "created_at": { 1073 + "name": "created_at", 1074 + "type": "timestamp", 1075 + "primaryKey": false, 1076 + "notNull": true, 1077 + "default": "now()" 1078 + }, 1079 + "updated_at": { 1080 + "name": "updated_at", 1081 + "type": "timestamp", 1082 + "primaryKey": false, 1083 + "notNull": true, 1084 + "default": "now()" 1085 + } 1086 + }, 1087 + "indexes": {}, 1088 + "foreignKeys": {}, 1089 + "compositePrimaryKeys": {}, 1090 + "uniqueConstraints": { 1091 + "users_did_unique": { 1092 + "name": "users_did_unique", 1093 + "nullsNotDistinct": false, 1094 + "columns": [ 1095 + "did" 1096 + ] 1097 + }, 1098 + "users_handle_unique": { 1099 + "name": "users_handle_unique", 1100 + "nullsNotDistinct": false, 1101 + "columns": [ 1102 + "handle" 1103 + ] 1104 + } 1105 + }, 1106 + "policies": {}, 1107 + "checkConstraints": {}, 1108 + "isRLSEnabled": false 1109 + }, 1110 + "public.variables": { 1111 + "name": "variables", 1112 + "schema": "", 1113 + "columns": { 1114 + "id": { 1115 + "name": "id", 1116 + "type": "text", 1117 + "primaryKey": true, 1118 + "notNull": true, 1119 + "default": "variable_id()" 1120 + }, 1121 + "name": { 1122 + "name": "name", 1123 + "type": "text", 1124 + "primaryKey": false, 1125 + "notNull": true 1126 + }, 1127 + "value": { 1128 + "name": "value", 1129 + "type": "text", 1130 + "primaryKey": false, 1131 + "notNull": true 1132 + }, 1133 + "created_at": { 1134 + "name": "created_at", 1135 + "type": "timestamp", 1136 + "primaryKey": false, 1137 + "notNull": true, 1138 + "default": "now()" 1139 + }, 1140 + "updated_at": { 1141 + "name": "updated_at", 1142 + "type": "timestamp", 1143 + "primaryKey": false, 1144 + "notNull": true, 1145 + "default": "now()" 1146 + } 1147 + }, 1148 + "indexes": {}, 1149 + "foreignKeys": {}, 1150 + "compositePrimaryKeys": {}, 1151 + "uniqueConstraints": {}, 1152 + "policies": {}, 1153 + "checkConstraints": {}, 1154 + "isRLSEnabled": false 1155 + }, 1156 + "public.volumes": { 1157 + "name": "volumes", 1158 + "schema": "", 1159 + "columns": { 1160 + "id": { 1161 + "name": "id", 1162 + "type": "text", 1163 + "primaryKey": true, 1164 + "notNull": true, 1165 + "default": "volume_id()" 1166 + }, 1167 + "slug": { 1168 + "name": "slug", 1169 + "type": "text", 1170 + "primaryKey": false, 1171 + "notNull": true 1172 + }, 1173 + "size": { 1174 + "name": "size", 1175 + "type": "integer", 1176 + "primaryKey": false, 1177 + "notNull": true 1178 + }, 1179 + "size_unit": { 1180 + "name": "size_unit", 1181 + "type": "text", 1182 + "primaryKey": false, 1183 + "notNull": true 1184 + }, 1185 + "created_at": { 1186 + "name": "created_at", 1187 + "type": "timestamp", 1188 + "primaryKey": false, 1189 + "notNull": true, 1190 + "default": "now()" 1191 + }, 1192 + "updated_at": { 1193 + "name": "updated_at", 1194 + "type": "timestamp", 1195 + "primaryKey": false, 1196 + "notNull": true, 1197 + "default": "now()" 1198 + } 1199 + }, 1200 + "indexes": {}, 1201 + "foreignKeys": {}, 1202 + "compositePrimaryKeys": {}, 1203 + "uniqueConstraints": { 1204 + "volumes_slug_unique": { 1205 + "name": "volumes_slug_unique", 1206 + "nullsNotDistinct": false, 1207 + "columns": [ 1208 + "slug" 1209 + ] 1210 + } 1211 + }, 1212 + "policies": {}, 1213 + "checkConstraints": {}, 1214 + "isRLSEnabled": false 1215 + }, 1216 + "public.integrations": { 1217 + "name": "integrations", 1218 + "schema": "", 1219 + "columns": { 1220 + "id": { 1221 + "name": "id", 1222 + "type": "text", 1223 + "primaryKey": true, 1224 + "notNull": true, 1225 + "default": "xata_id()" 1226 + }, 1227 + "sandbox_id": { 1228 + "name": "sandbox_id", 1229 + "type": "text", 1230 + "primaryKey": false, 1231 + "notNull": true 1232 + }, 1233 + "name": { 1234 + "name": "name", 1235 + "type": "text", 1236 + "primaryKey": false, 1237 + "notNull": true 1238 + }, 1239 + "description": { 1240 + "name": "description", 1241 + "type": "text", 1242 + "primaryKey": false, 1243 + "notNull": false 1244 + }, 1245 + "webhook_url": { 1246 + "name": "webhook_url", 1247 + "type": "text", 1248 + "primaryKey": false, 1249 + "notNull": true 1250 + }, 1251 + "created_at": { 1252 + "name": "created_at", 1253 + "type": "timestamp", 1254 + "primaryKey": false, 1255 + "notNull": true, 1256 + "default": "now()" 1257 + } 1258 + }, 1259 + "indexes": { 1260 + "unique_sandbox_integration": { 1261 + "name": "unique_sandbox_integration", 1262 + "columns": [ 1263 + { 1264 + "expression": "sandbox_id", 1265 + "isExpression": false, 1266 + "asc": true, 1267 + "nulls": "last" 1268 + }, 1269 + { 1270 + "expression": "name", 1271 + "isExpression": false, 1272 + "asc": true, 1273 + "nulls": "last" 1274 + } 1275 + ], 1276 + "isUnique": true, 1277 + "concurrently": false, 1278 + "method": "btree", 1279 + "with": {} 1280 + } 1281 + }, 1282 + "foreignKeys": { 1283 + "integrations_sandbox_id_sandboxes_id_fk": { 1284 + "name": "integrations_sandbox_id_sandboxes_id_fk", 1285 + "tableFrom": "integrations", 1286 + "tableTo": "sandboxes", 1287 + "columnsFrom": [ 1288 + "sandbox_id" 1289 + ], 1290 + "columnsTo": [ 1291 + "id" 1292 + ], 1293 + "onDelete": "no action", 1294 + "onUpdate": "no action" 1295 + } 1296 + }, 1297 + "compositePrimaryKeys": {}, 1298 + "uniqueConstraints": {}, 1299 + "policies": {}, 1300 + "checkConstraints": {}, 1301 + "isRLSEnabled": false 1302 + } 1303 + }, 1304 + "enums": {}, 1305 + "schemas": {}, 1306 + "sequences": {}, 1307 + "roles": {}, 1308 + "policies": {}, 1309 + "views": {}, 1310 + "_meta": { 1311 + "columns": {}, 1312 + "schemas": {}, 1313 + "tables": {} 1314 + } 1315 + }
+28
apps/cf-sandbox/drizzle/meta/_journal.json
··· 155 155 "when": 1773207199352, 156 156 "tag": "0021_romantic_morlocks", 157 157 "breakpoints": true 158 + }, 159 + { 160 + "idx": 22, 161 + "version": "7", 162 + "when": 1773212670865, 163 + "tag": "0022_dry_mojo", 164 + "breakpoints": true 165 + }, 166 + { 167 + "idx": 23, 168 + "version": "7", 169 + "when": 1773213459373, 170 + "tag": "0023_brown_mulholland_black", 171 + "breakpoints": true 172 + }, 173 + { 174 + "idx": 24, 175 + "version": "7", 176 + "when": 1773213776188, 177 + "tag": "0024_nasty_miek", 178 + "breakpoints": true 179 + }, 180 + { 181 + "idx": 25, 182 + "version": "7", 183 + "when": 1773219945973, 184 + "tag": "0025_worthless_old_lace", 185 + "breakpoints": true 158 186 } 159 187 ] 160 188 }
+4
apps/cf-sandbox/src/schema/index.ts
··· 9 9 import sandboxVolumes from "./sandbox-volumes"; 10 10 import files from "./files"; 11 11 import sandboxFiles from "./sandbox-files"; 12 + import tailscaleAuthKeys from "./tailscale-auth-keys"; 13 + import sshKeys from "./ssh-keys"; 12 14 13 15 export { 14 16 sandboxes, ··· 22 24 sandboxVolumes, 23 25 files, 24 26 sandboxFiles, 27 + tailscaleAuthKeys, 28 + sshKeys, 25 29 };
+17 -11
apps/cf-sandbox/src/schema/ssh-keys.ts
··· 1 1 import { type InferInsertModel, type InferSelectModel, sql } from "drizzle-orm"; 2 - import { pgTable, text, timestamp } from "drizzle-orm/pg-core"; 2 + import { pgTable, text, timestamp, uniqueIndex } from "drizzle-orm/pg-core"; 3 3 import sandboxes from "./sandboxes"; 4 4 5 - const sshKeys = pgTable("ssh_keys", { 6 - id: text("id") 7 - .primaryKey() 8 - .default(sql`xata_id()`), 9 - sandboxId: text("sandbox_id").references(() => sandboxes.id), 10 - publicKey: text("public_key").notNull(), 11 - privateKey: text("private_key").notNull(), 12 - redacted: text("redacted").notNull(), 13 - createdAt: timestamp("created_at").defaultNow().notNull(), 14 - }); 5 + const sshKeys = pgTable( 6 + "ssh_keys", 7 + { 8 + id: text("id") 9 + .primaryKey() 10 + .default(sql`xata_id()`), 11 + sandboxId: text("sandbox_id") 12 + .notNull() 13 + .references(() => sandboxes.id), 14 + publicKey: text("public_key").notNull(), 15 + privateKey: text("private_key").notNull(), 16 + redacted: text("redacted"), 17 + createdAt: timestamp("created_at").defaultNow().notNull(), 18 + }, 19 + (t) => [uniqueIndex("unique_sandbox_ssh_key").on(t.publicKey, t.sandboxId)], 20 + ); 15 21 16 22 export type SelectSshKey = InferSelectModel<typeof sshKeys>; 17 23 export type InsertSshKey = InferInsertModel<typeof sshKeys>;
+20
apps/cf-sandbox/src/schema/tailscale-auth-keys.ts
··· 1 + import { type InferInsertModel, type InferSelectModel, sql } from "drizzle-orm"; 2 + import { pgTable, text, timestamp } from "drizzle-orm/pg-core"; 3 + import sandboxes from "./sandboxes"; 4 + 5 + const tailscaleAuthKey = pgTable("tailscale_auth_keys", { 6 + id: text("id") 7 + .primaryKey() 8 + .default(sql`xata_id()`), 9 + sandboxId: text("sandbox_id") 10 + .notNull() 11 + .references(() => sandboxes.id), 12 + authKey: text("auth_key").notNull(), 13 + redacted: text("redacted").notNull(), 14 + createdAt: timestamp("created_at").defaultNow().notNull(), 15 + }); 16 + 17 + export type SelectTailscaleAuthKey = InferSelectModel<typeof tailscaleAuthKey>; 18 + export type InsertTailscaleAuthKey = InferInsertModel<typeof tailscaleAuthKey>; 19 + 20 + export default tailscaleAuthKey;
-18
apps/cf-sandbox/src/schema/tailscale-tokens.ts
··· 1 - import { type InferInsertModel, type InferSelectModel, sql } from "drizzle-orm"; 2 - import { pgTable, text, timestamp } from "drizzle-orm/pg-core"; 3 - import sandboxes from "./sandboxes"; 4 - 5 - const tailscaleTokens = pgTable("tailscale_tokens", { 6 - id: text("id") 7 - .primaryKey() 8 - .default(sql`xata_id()`), 9 - sandboxId: text("sandbox_id").references(() => sandboxes.id), 10 - tokens: text("tokens").notNull(), 11 - redacted: text("redacted").notNull(), 12 - createdAt: timestamp("created_at").defaultNow().notNull(), 13 - }); 14 - 15 - export type SelectTailscaleToken = InferSelectModel<typeof tailscaleTokens>; 16 - export type InsertTailscaleToken = InferInsertModel<typeof tailscaleTokens>; 17 - 18 - export default tailscaleTokens;
+4
apps/sandbox/src/schema/mod.ts
··· 9 9 import sandboxVolumes from "./sandbox-volumes.ts"; 10 10 import files from "./files.ts"; 11 11 import sandboxFiles from "./sandbox-files.ts"; 12 + import sshKeys from "./ssh-keys.ts"; 13 + import tailscaleAuthKeys from "./tailscale-auth-keys.ts"; 12 14 13 15 export { 14 16 sandboxes, ··· 22 24 sandboxVolumes, 23 25 files, 24 26 sandboxFiles, 27 + sshKeys, 28 + tailscaleAuthKeys, 25 29 };
+17 -11
apps/sandbox/src/schema/ssh-keys.ts
··· 1 1 import { type InferInsertModel, type InferSelectModel, sql } from "drizzle-orm"; 2 - import { pgTable, text, timestamp } from "drizzle-orm/pg-core"; 2 + import { pgTable, text, timestamp, uniqueIndex } from "drizzle-orm/pg-core"; 3 3 import sandboxes from "./sandboxes.ts"; 4 4 5 - const sshKeys = pgTable("ssh_keys", { 6 - id: text("id") 7 - .primaryKey() 8 - .default(sql`xata_id()`), 9 - sandboxId: text("sandbox_id").references(() => sandboxes.id), 10 - publicKey: text("public_key").notNull(), 11 - privateKey: text("private_key").notNull(), 12 - redacted: text("redacted").notNull(), 13 - createdAt: timestamp("created_at").defaultNow().notNull(), 14 - }); 5 + const sshKeys = pgTable( 6 + "ssh_keys", 7 + { 8 + id: text("id") 9 + .primaryKey() 10 + .default(sql`xata_id()`), 11 + sandboxId: text("sandbox_id") 12 + .notNull() 13 + .references(() => sandboxes.id), 14 + publicKey: text("public_key").notNull(), 15 + privateKey: text("private_key").notNull(), 16 + redacted: text("redacted").notNull(), 17 + createdAt: timestamp("created_at").defaultNow().notNull(), 18 + }, 19 + (t) => [uniqueIndex("unique_sandbox_ssh_key").on(t.publicKey, t.sandboxId)], 20 + ); 15 21 16 22 export type SelectSshKey = InferSelectModel<typeof sshKeys>; 17 23 export type InsertSshKey = InferInsertModel<typeof sshKeys>;
+20
apps/sandbox/src/schema/tailscale-auth-keys.ts
··· 1 + import { type InferInsertModel, type InferSelectModel, sql } from "drizzle-orm"; 2 + import { pgTable, text, timestamp } from "drizzle-orm/pg-core"; 3 + import sandboxes from "./sandboxes.ts"; 4 + 5 + const tailscaleAuthKey = pgTable("tailscale_auth_keys", { 6 + id: text("id") 7 + .primaryKey() 8 + .default(sql`xata_id()`), 9 + sandboxId: text("sandbox_id") 10 + .notNull() 11 + .references(() => sandboxes.id), 12 + authKey: text("auth_key").notNull(), 13 + redacted: text("redacted").notNull(), 14 + createdAt: timestamp("created_at").defaultNow().notNull(), 15 + }); 16 + 17 + export type SelectTailscaleAuthKey = InferSelectModel<typeof tailscaleAuthKey>; 18 + export type InsertTailscaleAuthKey = InferInsertModel<typeof tailscaleAuthKey>; 19 + 20 + export default tailscaleAuthKey;
-18
apps/sandbox/src/schema/tailscale-tokens.ts
··· 1 - import { type InferInsertModel, type InferSelectModel, sql } from "drizzle-orm"; 2 - import { pgTable, text, timestamp } from "drizzle-orm/pg-core"; 3 - import sandboxes from "./sandboxes.ts"; 4 - 5 - const tailscaleTokens = pgTable("tailscale_tokens", { 6 - id: text("id") 7 - .primaryKey() 8 - .default(sql`xata_id()`), 9 - sandboxId: text("sandbox_id").references(() => sandboxes.id), 10 - tokens: text("tokens").notNull(), 11 - redacted: text("redacted").notNull(), 12 - createdAt: timestamp("created_at").defaultNow().notNull(), 13 - }); 14 - 15 - export type SelectTailscaleToken = InferSelectModel<typeof tailscaleTokens>; 16 - export type InsertTailscaleToken = InferInsertModel<typeof tailscaleTokens>; 17 - 18 - export default tailscaleTokens;
+33
apps/web/src/api/sshkey.ts
··· 1 + import { client } from "."; 2 + import type { SshKeys } from "../types/sshkeys"; 3 + 4 + export const saveSshKeys = ( 5 + sandboxId: string, 6 + privateKey: string, 7 + publicKey: string, 8 + redacted: string, 9 + ) => 10 + client.post( 11 + "/xrpc/io.pocketenv.sandbox.putSshKeys", 12 + { 13 + id: sandboxId, 14 + privateKey, 15 + publicKey, 16 + redacted, 17 + }, 18 + { 19 + headers: { 20 + Authorization: `Bearer ${localStorage.getItem("token")}`, 21 + }, 22 + }, 23 + ); 24 + 25 + export const getSshKeys = (sandboxId: string) => 26 + client.get<SshKeys>("/xrpc/io.pocketenv.sandbox.getSshKeys", { 27 + params: { 28 + id: sandboxId, 29 + }, 30 + headers: { 31 + Authorization: `Bearer ${localStorage.getItem("token")}`, 32 + }, 33 + });
+34
apps/web/src/api/tailscale-auth-key.ts
··· 1 + import { client } from "."; 2 + import type { TailscaleAuthKey } from "../types/tailscale-auth-key"; 3 + 4 + export const saveTailscaleAuthKey = ( 5 + sandboxId: string, 6 + authKey: string, 7 + redacted: string, 8 + ) => 9 + client.post( 10 + "/xrpc/io.pocketenv.sandbox.putTailscaleAuthKey", 11 + { 12 + id: sandboxId, 13 + authKey, 14 + redacted, 15 + }, 16 + { 17 + headers: { 18 + Authorization: `Bearer ${localStorage.getItem("token")}`, 19 + }, 20 + }, 21 + ); 22 + 23 + export const getTailscaleAuthKey = (sandboxId: string) => 24 + client.get<TailscaleAuthKey>( 25 + "/xrpc/io.pocketenv.sandbox.getTailscaleAuthKey", 26 + { 27 + params: { 28 + id: sandboxId, 29 + }, 30 + headers: { 31 + Authorization: `Bearer ${localStorage.getItem("token")}`, 32 + }, 33 + }, 34 + );
+25
apps/web/src/hooks/useSshKeys.ts
··· 1 + import { useMutation, useQuery } from "@tanstack/react-query"; 1 2 import sodium from "libsodium-wrappers"; 3 + import { saveSshKeys, getSshKeys } from "../api/sshkey"; 2 4 3 5 export type SSHKeyPair = { 4 6 publicKey: string; ··· 124 126 125 127 return { generateEd25519SSHKeyPair }; 126 128 } 129 + 130 + export const useSaveSshKeyMutation = () => 131 + useMutation({ 132 + mutationFn: (variables: { 133 + sandboxId: string; 134 + publicKey: string; 135 + privateKey: string; 136 + redacted: string; 137 + }) => 138 + saveSshKeys( 139 + variables.sandboxId, 140 + variables.privateKey, 141 + variables.publicKey, 142 + variables.redacted, 143 + ), 144 + }); 145 + 146 + export const useSshKeysQuery = (sandboxId: string) => 147 + useQuery({ 148 + queryKey: ["sshKeys", sandboxId], 149 + queryFn: () => getSshKeys(sandboxId), 150 + enabled: !!sandboxId, 151 + });
+26
apps/web/src/hooks/useTailscaleAuthKey.ts
··· 1 + import { useMutation, useQuery } from "@tanstack/react-query"; 2 + import { 3 + getTailscaleAuthKey, 4 + saveTailscaleAuthKey, 5 + } from "../api/tailscale-auth-key"; 6 + 7 + export const useTailscaleAuthKeyQuery = (sandboxId: string) => 8 + useQuery({ 9 + queryKey: ["tailscale-auth-key", sandboxId], 10 + queryFn: () => getTailscaleAuthKey(sandboxId), 11 + enabled: !!sandboxId, 12 + }); 13 + 14 + export const useSaveTailscaleAuthKeyMutation = () => 15 + useMutation({ 16 + mutationFn: (variables: { 17 + sandboxId: string; 18 + authKey: string; 19 + redacted: string; 20 + }) => 21 + saveTailscaleAuthKey( 22 + variables.sandboxId, 23 + variables.authKey, 24 + variables.redacted, 25 + ), 26 + });
+59 -3
apps/web/src/pages/settings/sshkeys/SshKeys.tsx
··· 5 5 import { useSandboxQuery } from "../../../hooks/useSandbox"; 6 6 import Main from "../../../layouts/Main"; 7 7 import Sidebar from "../sidebar/Sidebar"; 8 - import { useSshKeys } from "../../../hooks/useSshKeys"; 8 + import { 9 + useSaveSshKeyMutation, 10 + useSshKeys, 11 + useSshKeysQuery, 12 + } from "../../../hooks/useSshKeys"; 9 13 import { useNotyf } from "../../../hooks/useNotyf"; 14 + import { useSodium } from "../../../hooks/useSodium"; 15 + import { PUBLIC_KEY } from "../../../consts"; 16 + import { useEffect } from "react"; 17 + import { useQueryClient } from "@tanstack/react-query"; 10 18 11 19 const sshKeysSchema = z 12 20 .object({ ··· 58 66 type SshKeysFormValues = z.infer<typeof sshKeysSchema>; 59 67 60 68 function SshKeys() { 69 + const sodium = useSodium(); 61 70 const notyf = useNotyf(); 71 + const queryClient = useQueryClient(); 62 72 const routerState = useRouterState(); 63 73 const pathname = routerState.location.pathname; 64 74 const { generateEd25519SSHKeyPair } = useSshKeys(); ··· 66 76 `at:/${pathname.replace("/ssh-keys", "").replace("sandbox", "io.pocketenv.sandbox")}`, 67 77 ); 68 78 79 + const { mutateAsync: saveSshKeys } = useSaveSshKeyMutation(); 80 + const { data: sshKeys } = useSshKeysQuery(data?.sandbox?.id || ""); 81 + 69 82 const { 70 83 register, 71 84 handleSubmit, ··· 75 88 resolver: zodResolver(sshKeysSchema), 76 89 }); 77 90 78 - const onSubmit = (values: SshKeysFormValues) => { 79 - console.log(values); 91 + useEffect(() => { 92 + if (sshKeys?.data) { 93 + setValue("privateKey", sshKeys.data.privateKey); 94 + setValue("publicKey", sshKeys.data.publicKey); 95 + } 96 + }, [sshKeys, setValue]); 97 + 98 + const onSubmit = async (values: SshKeysFormValues) => { 99 + if (!values.privateKey.includes("****")) { 100 + const sealed = sodium.cryptoBoxSeal( 101 + sodium.fromString(values.privateKey), 102 + sodium.fromHex(PUBLIC_KEY), 103 + ); 104 + 105 + await saveSshKeys({ 106 + sandboxId: data!.sandbox!.id, 107 + privateKey: sodium.toBase64( 108 + sealed, 109 + sodium.base64Variants.URLSAFE_NO_PADDING, 110 + ), 111 + publicKey: values.publicKey, 112 + redacted: (() => { 113 + const header = "-----BEGIN OPENSSH PRIVATE KEY-----"; 114 + const footer = "-----END OPENSSH PRIVATE KEY-----"; 115 + const headerIndex = values.privateKey.indexOf(header); 116 + const footerIndex = values.privateKey.indexOf(footer); 117 + if (headerIndex === -1 || footerIndex === -1) 118 + return values.privateKey; 119 + const body = values.privateKey 120 + .slice(headerIndex + header.length, footerIndex) 121 + .trim(); 122 + const maskedBody = 123 + body.length > 15 124 + ? body.slice(0, 10) + 125 + "*".repeat(body.length - 15) + 126 + body.slice(-5) 127 + : body; 128 + return `${header}\n${maskedBody}\n${footer}`; 129 + })(), 130 + }); 131 + } 132 + 80 133 notyf.open("primary", "SSH keys saved successfully!"); 134 + await queryClient.invalidateQueries({ 135 + queryKey: ["sshKeys", data?.sandbox?.id], 136 + }); 81 137 }; 82 138 83 139 const onGenerate = async () => {
+46 -2
apps/web/src/pages/settings/tailscale/Tailscale.tsx
··· 6 6 import Main from "../../../layouts/Main"; 7 7 import Sidebar from "../sidebar/Sidebar"; 8 8 import { useNotyf } from "../../../hooks/useNotyf"; 9 + import { 10 + useSaveTailscaleAuthKeyMutation, 11 + useTailscaleAuthKeyQuery, 12 + } from "../../../hooks/useTailscaleAuthKey"; 13 + import { useSodium } from "../../../hooks/useSodium"; 14 + import { PUBLIC_KEY } from "../../../consts"; 15 + import { useEffect } from "react"; 16 + import { useQueryClient } from "@tanstack/react-query"; 9 17 10 18 const tailscaleSchema = z.object({ 11 19 authKey: z 12 20 .string() 21 + .min(15) 13 22 .trim() 14 23 .refine((val) => val === "" || val.startsWith("tskey-auth-"), { 15 24 message: "Auth Key must start with tskey-auth-", ··· 21 30 22 31 function Tailscale() { 23 32 const notyf = useNotyf(); 33 + const queryClient = useQueryClient(); 34 + const sodium = useSodium(); 24 35 const routerState = useRouterState(); 25 36 const pathname = routerState.location.pathname; 37 + const { mutateAsync: saveTailscaleAuthKey } = 38 + useSaveTailscaleAuthKeyMutation(); 26 39 const { data } = useSandboxQuery( 27 40 `at:/${pathname.replace("/tailscale", "").replace("sandbox", "io.pocketenv.sandbox")}`, 28 41 ); 42 + const { data: tailscaleAuthKey } = useTailscaleAuthKeyQuery( 43 + data?.sandbox?.id || "", 44 + ); 29 45 30 46 const { 31 47 register, 32 48 handleSubmit, 49 + setValue, 33 50 formState: { errors }, 34 51 } = useForm<TailscaleFormValues>({ 35 52 resolver: zodResolver(tailscaleSchema), 36 53 }); 37 54 38 - const onSubmit = (values: TailscaleFormValues) => { 39 - console.log(values); 55 + useEffect(() => { 56 + if (tailscaleAuthKey?.data) { 57 + setValue("authKey", tailscaleAuthKey.data.authKey); 58 + } 59 + }, [tailscaleAuthKey, setValue]); 60 + 61 + const onSubmit = async (values: TailscaleFormValues) => { 62 + if (values.authKey && !values.authKey.includes("**")) { 63 + const sealed = sodium.cryptoBoxSeal( 64 + sodium.fromString(values.authKey), 65 + sodium.fromHex(PUBLIC_KEY), 66 + ); 67 + await saveTailscaleAuthKey({ 68 + sandboxId: data!.sandbox!.id, 69 + authKey: sodium.toBase64( 70 + sealed, 71 + sodium.base64Variants.URLSAFE_NO_PADDING, 72 + ), 73 + redacted: 74 + values.authKey.length > 14 75 + ? values.authKey.slice(0, 11) + 76 + "*".repeat(values.authKey.length - 14) + 77 + values.authKey.slice(-3) 78 + : values.authKey, 79 + }); 80 + } 40 81 notyf.open("primary", "Auth Key saved successfully!"); 82 + await queryClient.invalidateQueries({ 83 + queryKey: ["tailscaleAuthKey", data?.sandbox?.id], 84 + }); 41 85 }; 42 86 43 87 return (
+6
apps/web/src/types/sshkeys.ts
··· 1 + export type SshKeys = { 2 + id: string; 3 + privateKey: string; 4 + publicKey: string; 5 + createdAt: string; 6 + };
+5
apps/web/src/types/tailscale-auth-key.ts
··· 1 + export type TailscaleAuthKey = { 2 + id: string; 3 + authKey: string; 4 + createdAt: string; 5 + };