11import { openSelectedProjectBrowser } from "./actions-browser.js"
22import { openSelectedProjectDatabaseEditor } from "./actions-databases.js"
3+ import { readEventPayloadString } from "./actions-event-payload.js"
34import { appendOutputLine , appendOutputLineHandler , notifyProjectEventRateLimit } from "./actions-output.js"
45import { openSelectedProjectPort } from "./actions-port-forwards.js"
56import {
@@ -13,9 +14,9 @@ import {
1314} from "./actions-shared.js"
1415import { loadSelectedProjectTasks } from "./actions-tasks.js"
1516import {
17+ type ApiEvent ,
1618 applyAllProjects ,
1719 applyProject ,
18- type ApiEvent ,
1920 deleteProject ,
2021 downAllProjects ,
2122 downProject ,
@@ -79,41 +80,33 @@ const resolveProjectTerminalKey = (
7980}
8081
8182const randomHex = ( bytes : number ) : string => {
82- const getRandomValues = globalThis . crypto ?. getRandomValues
83- if ( typeof getRandomValues === "function" ) {
84- const values = new Uint8Array ( bytes )
85- getRandomValues . call ( globalThis . crypto , values )
86- return Array . from ( values , ( value ) => value . toString ( 16 ) . padStart ( 2 , "0" ) ) . join ( "" )
87- }
88-
89- let fallback = ""
90- while ( fallback . length < bytes * 2 ) {
91- fallback += Math . floor ( Math . random ( ) * 0x1_0000_0000 )
92- . toString ( 16 )
93- . padStart ( 8 , "0" )
94- }
95- return fallback . slice ( 0 , bytes * 2 )
83+ const values = new Uint8Array ( bytes )
84+ globalThis . crypto . getRandomValues ( values )
85+ return Array . from ( values , ( value ) => value . toString ( 16 ) . padStart ( 2 , "0" ) ) . join ( "" )
9686}
9787
9888const createPendingTerminalSessionId = ( ) : string => {
99- const randomUUID = globalThis . crypto ?. randomUUID
100- if ( typeof randomUUID === "function" ) {
101- return randomUUID . call ( globalThis . crypto )
89+ if ( Reflect . has ( globalThis . crypto , "randomUUID" ) ) {
90+ return globalThis . crypto . randomUUID ( )
10291 }
10392
10493 return `pending-${ Date . now ( ) . toString ( 16 ) } -${ randomHex ( 8 ) } `
10594}
10695
107- const readEventPayloadString = (
108- event : ApiEvent ,
109- key : string
110- ) : string | null => {
111- const payload = event . payload
112- if ( payload === null || typeof payload !== "object" || Array . isArray ( payload ) ) {
113- return null
114- }
115- const value = Object . entries ( payload ) . find ( ( [ name ] ) => name === key ) ?. [ 1 ]
116- return typeof value === "string" ? value : null
96+ type ProjectActiveTerminalSessionArgs = Omit <
97+ Parameters < typeof buildProjectActiveTerminalSession > [ 0 ] ,
98+ "onExit" | "onReady"
99+ >
100+
101+ const addProjectTerminalSession = (
102+ context : BrowserActionContext ,
103+ args : ProjectActiveTerminalSessionArgs
104+ ) => {
105+ context . addTerminalSession ( buildProjectActiveTerminalSession ( {
106+ ...args ,
107+ onExit : context . reloadDashboard ,
108+ onReady : context . reloadDashboard
109+ } ) )
117110}
118111
119112const readTerminalSessionCreatedId = (
@@ -188,6 +181,11 @@ export const connectProjectById = (
188181 stream ?. close ( )
189182 stream = null
190183 }
184+ const showPendingTerminalError = ( error : string ) => {
185+ pendingSessionFinalized = true
186+ appendOutputLine ( context , `[error] ${ error } ` )
187+ context . addTerminalSession ( renderPendingTerminalSession ( error , "error" ) )
188+ }
191189 const attachCreatedSession = ( sessionId : string ) => {
192190 if ( attachedSessionId !== null ) {
193191 return
@@ -198,23 +196,19 @@ export const connectProjectById = (
198196 effect : loadProjectTerminalSession ( resolvedProjectKey , sessionId ) ,
199197 label : "Attaching SSH terminal" ,
200198 onFailure : ( error ) => {
201- pendingSessionFinalized = true
202- appendOutputLine ( context , `[error] ${ error } ` )
203- context . addTerminalSession ( renderPendingTerminalSession ( error , "error" ) )
199+ showPendingTerminalError ( error )
204200 closeStream ( )
205201 } ,
206202 onSuccess : ( session ) => {
207203 pendingSessionFinalized = true
208204 context . reloadDashboard ( )
209205 context . closeTerminalSession ( pendingSessionId )
210- context . addTerminalSession ( buildProjectActiveTerminalSession ( {
211- onExit : context . reloadDashboard ,
212- onReady : context . reloadDashboard ,
206+ addProjectTerminalSession ( context , {
213207 projectDisplayName,
214208 projectId,
215209 projectKey : resolvedProjectKey ,
216210 session
217- } ) )
211+ } )
218212 context . setMessage ( `Project is ready. SSH terminal is connecting for ${ projectDisplayName } .` )
219213 closeStream ( )
220214 }
@@ -225,9 +219,7 @@ export const connectProjectById = (
225219 effect : startProjectTerminalSession ( resolvedProjectKey , pendingSessionId ) ,
226220 label : "Opening SSH terminal" ,
227221 onFailure : ( error ) => {
228- pendingSessionFinalized = true
229- appendOutputLine ( context , `[error] ${ error } ` )
230- context . addTerminalSession ( renderPendingTerminalSession ( error , "error" ) )
222+ showPendingTerminalError ( error )
231223 } ,
232224 onSuccess : ( accepted ) => {
233225 appendOutputLine ( context , `[ssh.prepare] SSH terminal request accepted (${ accepted . requestId } )` )
@@ -237,9 +229,7 @@ export const connectProjectById = (
237229 onEvent : ( event ) => {
238230 const failure = readTerminalStartupFailure ( event , accepted . requestId )
239231 if ( failure !== null ) {
240- pendingSessionFinalized = true
241- appendOutputLine ( context , `[error] ${ failure } ` )
242- context . addTerminalSession ( renderPendingTerminalSession ( failure , "error" ) )
232+ showPendingTerminalError ( failure )
243233 context . setMessage ( failure )
244234 closeStream ( )
245235 return
@@ -306,14 +296,12 @@ export const attachProjectTerminalById = (
306296 effect : loadProjectTerminalSession ( resolvedProjectKey , sessionId ) ,
307297 label : "Attaching SSH terminal" ,
308298 onSuccess : ( session ) => {
309- context . addTerminalSession ( buildProjectActiveTerminalSession ( {
310- onExit : context . reloadDashboard ,
311- onReady : context . reloadDashboard ,
299+ addProjectTerminalSession ( context , {
312300 projectDisplayName,
313301 projectId,
314302 projectKey : resolvedProjectKey ,
315303 session
316- } ) )
304+ } )
317305 context . setMessage ( `Attached SSH terminal for ${ projectDisplayName } .` )
318306 }
319307 } )
0 commit comments