@@ -4,15 +4,13 @@ export interface BackupOptions {
44 dir : string ;
55 excludes ?: string [ ] ;
66 gitignore ?: boolean ;
7- localBucket ?: boolean ;
87 name ?: string ;
98 ttl ?: number ;
109}
1110
1211export interface DirectoryBackup {
1312 dir : string ;
1413 id : string ;
15- localBucket ?: boolean ;
1614}
1715
1816export interface ExecOptions {
@@ -175,22 +173,14 @@ export const ProjectUnexposePortInputSchema = z
175173export const ProjectCreateBackupInputSchema = z
176174 . object ( {
177175 dir : WorkspacePathSchema . default ( "/workspace" ) ,
178- localBucket : z . boolean ( ) . optional ( ) ,
179176 name : z . string ( ) . min ( 1 ) . max ( 200 ) . optional ( ) ,
180- ttl : z
181- . number ( )
182- . int ( )
183- . positive ( )
184- . max ( 90 * 24 * 60 * 60 )
185- . default ( 30 * 24 * 60 * 60 ) ,
186177 } )
187178 . strict ( ) ;
188179
189180export const ProjectBackupHandleSchema = z
190181 . object ( {
191182 id : z . string ( ) . min ( 1 ) ,
192183 dir : WorkspacePathSchema ,
193- localBucket : z . boolean ( ) . optional ( ) ,
194184 } )
195185 . strict ( ) ;
196186
@@ -292,7 +282,6 @@ export interface NormalizedExposePortResult {
292282export interface NormalizedBackupHandle {
293283 id : string ;
294284 dir : string ;
295- localBucket ?: boolean ;
296285}
297286
298287function isSafeWorkspacePath ( path : string ) : boolean {
@@ -320,219 +309,10 @@ function normalizeWorkspacePath(path: string): string {
320309 return `/${ parts . join ( "/" ) } ${ path . endsWith ( "/" ) ? "/" : "" } ` ;
321310}
322311
323- interface SandboxExecutionResult {
324- logs : {
325- stdout : string [ ] ;
326- stderr : string [ ] ;
327- } ;
328- error ?: unknown ;
329- }
330-
331- function isSandboxExecutionResult ( value : unknown ) : value is SandboxExecutionResult {
332- if ( ! value || typeof value !== "object" ) {
333- return false ;
334- }
335- const candidate = value as Record < string , unknown > ;
336- const logs = candidate [ "logs" ] ;
337- if ( ! logs || typeof logs !== "object" ) {
338- return false ;
339- }
340- const typedLogs = logs as Record < string , unknown > ;
341- return Array . isArray ( typedLogs [ "stdout" ] ) && Array . isArray ( typedLogs [ "stderr" ] ) ;
342- }
343-
344- function toPlainExecutionResult ( value : unknown ) : unknown {
345- if (
346- value &&
347- typeof value === "object" &&
348- "toJSON" in value &&
349- typeof ( value as { toJSON ?: unknown } ) . toJSON === "function"
350- ) {
351- return ( value as { toJSON ( ) : unknown } ) . toJSON ( ) ;
352- }
353- return value ;
354- }
355-
356- function normalizeEncoding ( value : unknown ) : "utf8" | "base64" {
357- return value === "base64" ? "base64" : "utf8" ;
358- }
359-
360312function shellQuote ( arg : string ) : string {
361313 return `'${ arg . replaceAll ( "'" , "'\\''" ) } '` ;
362314}
363315
364316export function commandToShellString ( command : string [ ] ) : string {
365317 return command . map ( shellQuote ) . join ( " " ) ;
366318}
367-
368- export function createExecOptions ( input : ProjectExecInput ) : ExecOptions {
369- const options : ExecOptions = { } ;
370- if ( input . cwd ) {
371- options . cwd = input . cwd ;
372- }
373- if ( input . env ) {
374- options . env = input . env ;
375- }
376- if ( input . timeoutMs ) {
377- options . timeout = input . timeoutMs ;
378- }
379- return options ;
380- }
381-
382- export function createProcessOptions ( input : ProjectStartProcessInput ) : ProcessOptions {
383- const options : ProcessOptions = createExecOptions ( input ) ;
384- options . autoCleanup = false ;
385- if ( input . keepAliveTimeoutMs !== undefined ) {
386- options . keepAliveTimeoutMs = input . keepAliveTimeoutMs ;
387- }
388- if ( input . maxRestarts !== undefined ) {
389- options . maxRestarts = input . maxRestarts ;
390- }
391- if ( input . processId ) {
392- options . processId = input . processId ;
393- }
394- if ( input . restartOnFailure !== undefined ) {
395- options . restartOnFailure = input . restartOnFailure ;
396- }
397- return options ;
398- }
399-
400- export function createRunCodeOptions ( input : ProjectRunCodeInput ) : RunCodeOptions {
401- const options : RunCodeOptions = { language : input . language } ;
402- if ( input . env ) {
403- options . envVars = input . env ;
404- }
405- return options ;
406- }
407-
408- export function normalizeExecResult ( value : unknown ) : NormalizedExecResult {
409- const parsed = z
410- . object ( {
411- command : z . string ( ) ,
412- duration : z . number ( ) . nonnegative ( ) . optional ( ) ,
413- exitCode : z . number ( ) . int ( ) ,
414- stderr : z . string ( ) ,
415- stdout : z . string ( ) ,
416- success : z . boolean ( ) ,
417- } )
418- . passthrough ( )
419- . parse ( toPlainExecutionResult ( value ) ) ;
420- return {
421- command : parsed . command ,
422- stdout : parsed . stdout ,
423- stderr : parsed . stderr ,
424- success : parsed . success ,
425- exitCode : parsed . exitCode ,
426- ...( parsed . duration === undefined ? { } : { durationMs : parsed . duration } ) ,
427- } ;
428- }
429-
430- export function normalizeReadFileResult ( value : unknown ) : NormalizedReadFileResult {
431- const parsed = z
432- . object ( {
433- content : z . string ( ) ,
434- encoding : z . enum ( [ "utf-8" , "base64" ] ) . optional ( ) ,
435- path : z . string ( ) ,
436- size : z . number ( ) . int ( ) . nonnegative ( ) . optional ( ) ,
437- } )
438- . passthrough ( )
439- . parse ( value ) ;
440- return {
441- path : parsed . path ,
442- content : parsed . content ,
443- encoding : normalizeEncoding ( parsed . encoding ) ,
444- ...( parsed . size === undefined ? { } : { size : parsed . size } ) ,
445- } ;
446- }
447-
448- export function normalizeWriteFileResult ( value : unknown ) : NormalizedWriteFileResult {
449- const parsed = z . object ( { path : z . string ( ) , success : z . boolean ( ) } ) . passthrough ( ) . parse ( value ) ;
450- return {
451- path : parsed . path ,
452- success : parsed . success ,
453- } ;
454- }
455-
456- export function normalizeListFilesResult ( value : unknown ) : NormalizedListFilesResult {
457- const parsed = z
458- . object ( {
459- path : z . string ( ) ,
460- files : z . array (
461- z
462- . object ( {
463- absolutePath : z . string ( ) ,
464- modifiedAt : z . string ( ) ,
465- name : z . string ( ) ,
466- relativePath : z . string ( ) ,
467- size : z . number ( ) . int ( ) . nonnegative ( ) ,
468- type : z . enum ( [ "file" , "directory" , "symlink" , "other" ] ) ,
469- } )
470- . passthrough ( ) ,
471- ) ,
472- } )
473- . passthrough ( )
474- . parse ( value ) ;
475- return {
476- path : parsed . path ,
477- files : parsed . files . map ( ( file ) => ( {
478- name : file . name ,
479- path : file . absolutePath ,
480- relativePath : file . relativePath ,
481- type : file . type ,
482- size : file . size ,
483- modifiedAt : file . modifiedAt ,
484- } ) ) ,
485- } ;
486- }
487-
488- export function normalizeExposePortResult ( value : unknown ) : NormalizedExposePortResult {
489- const parsed = z
490- . object ( {
491- name : z . string ( ) . optional ( ) ,
492- port : z . number ( ) . int ( ) . positive ( ) ,
493- token : z . string ( ) . optional ( ) ,
494- url : z . string ( ) . url ( ) ,
495- } )
496- . passthrough ( )
497- . parse ( value ) ;
498- return {
499- port : parsed . port ,
500- ...( parsed . token === undefined ? { } : { token : parsed . token } ) ,
501- url : parsed . url ,
502- ...( parsed . name === undefined ? { } : { name : parsed . name } ) ,
503- } ;
504- }
505-
506- export function normalizeDirectoryBackup ( value : DirectoryBackup ) : NormalizedBackupHandle {
507- const parsed = ProjectBackupHandleSchema . parse ( value ) ;
508- return {
509- id : parsed . id ,
510- dir : parsed . dir ,
511- ...( parsed . localBucket === undefined ? { } : { localBucket : parsed . localBucket } ) ,
512- } ;
513- }
514-
515- export function createBackupOptions ( input : ProjectCreateBackupInput ) : BackupOptions {
516- const parsedInput = ProjectCreateBackupInputSchema . parse ( input ) ;
517- return {
518- dir : parsedInput . dir ,
519- ttl : parsedInput . ttl ,
520- gitignore : true ,
521- excludes : [ "node_modules" , ".git" , ".next" , ".turbo" ] ,
522- ...( parsedInput . localBucket === undefined ? { } : { localBucket : parsedInput . localBucket } ) ,
523- ...( parsedInput . name ? { name : parsedInput . name } : { } ) ,
524- } ;
525- }
526-
527- export function normalizeRunCodeResult ( value : unknown ) : NormalizedRunCodeResult {
528- const serialized = toPlainExecutionResult ( value ) ;
529- if ( ! isSandboxExecutionResult ( serialized ) ) {
530- throw new Error ( "Unexpected sandbox execution result." ) ;
531- }
532- return {
533- stdout : serialized . logs . stdout . join ( "" ) ,
534- stderr : serialized . logs . stderr . join ( "" ) ,
535- success : ! serialized . error ,
536- exitCode : serialized . error ? 1 : 0 ,
537- } ;
538- }
0 commit comments