@@ -21,8 +21,8 @@ import {
2121 respondUnavailableOnThrow ,
2222 safeParseJson ,
2323} from "./nodes.helpers.js" ;
24- import type { GatewayRequestHandlers , RespondFn } from "./types.js" ;
25- import { assertValidParams } from "./validation.js" ;
24+ import type { GatewayRequestContext , GatewayRequestHandlers , RespondFn } from "./types.js" ;
25+ import { assertValidParams , type Validator } from "./validation.js" ;
2626
2727function requireApprovalsBaseHash (
2828 params : unknown ,
@@ -90,13 +90,37 @@ function toExecApprovalsPayload(snapshot: ExecApprovalsSnapshot) {
9090 } ;
9191}
9292
93- function resolveNodeIdOrRespond ( nodeId : string , respond : RespondFn ) : string | null {
94- const id = nodeId . trim ( ) ;
95- if ( ! id ) {
96- respond ( false , undefined , errorShape ( ErrorCodes . INVALID_REQUEST , "nodeId required" ) ) ;
97- return null ;
93+ async function respondWithExecApprovalsNodePayload < TParams extends { nodeId : string } > ( params : {
94+ method : string ;
95+ rawParams : unknown ;
96+ validate : Validator < TParams > ;
97+ context : GatewayRequestContext ;
98+ respond : RespondFn ;
99+ command : "system.execApprovals.get" | "system.execApprovals.set" ;
100+ commandParams : ( parsedParams : TParams ) => Record < string , unknown > ;
101+ readPayload : ( response : { payload ?: unknown ; payloadJSON ?: string | null } ) => unknown ;
102+ } ) : Promise < void > {
103+ const rawParams = params . rawParams ;
104+ if ( ! assertValidParams ( rawParams , params . validate , params . method , params . respond ) ) {
105+ return ;
98106 }
99- return id ;
107+ const parsedParams = rawParams ;
108+ const nodeId = parsedParams . nodeId . trim ( ) ;
109+ if ( ! nodeId ) {
110+ params . respond ( false , undefined , errorShape ( ErrorCodes . INVALID_REQUEST , "nodeId required" ) ) ;
111+ return ;
112+ }
113+ await respondUnavailableOnThrow ( params . respond , async ( ) => {
114+ const res = await params . context . nodeRegistry . invoke ( {
115+ nodeId,
116+ command : params . command ,
117+ params : params . commandParams ( parsedParams ) ,
118+ } ) ;
119+ if ( ! respondUnavailableOnNodeInvokeError ( params . respond , res ) ) {
120+ return ;
121+ }
122+ params . respond ( true , params . readPayload ( res ) , undefined ) ;
123+ } ) ;
100124}
101125
102126export const execApprovalsHandlers : GatewayRequestHandlers = {
@@ -133,69 +157,34 @@ export const execApprovalsHandlers: GatewayRequestHandlers = {
133157 respond ( true , toExecApprovalsPayload ( nextSnapshot ) , undefined ) ;
134158 } ,
135159 "exec.approvals.node.get" : async ( { params, respond, context } ) => {
136- if (
137- ! assertValidParams (
138- params ,
139- validateExecApprovalsNodeGetParams ,
140- "exec.approvals.node.get" ,
141- respond ,
142- )
143- ) {
144- return ;
145- }
146- const { nodeId } = params as { nodeId : string } ;
147- const id = resolveNodeIdOrRespond ( nodeId , respond ) ;
148- if ( ! id ) {
149- return ;
150- }
151- await respondUnavailableOnThrow ( respond , async ( ) => {
152- const res = await context . nodeRegistry . invoke ( {
153- nodeId : id ,
154- command : "system.execApprovals.get" ,
155- params : { } ,
156- } ) ;
157- if ( ! respondUnavailableOnNodeInvokeError ( respond , res ) ) {
158- return ;
159- }
160+ await respondWithExecApprovalsNodePayload ( {
161+ method : "exec.approvals.node.get" ,
162+ rawParams : params ,
163+ validate : validateExecApprovalsNodeGetParams ,
164+ context,
165+ respond,
166+ command : "system.execApprovals.get" ,
167+ commandParams : ( ) => ( { } ) ,
160168 // Node invocations can return structured payloads or JSON strings
161169 // depending on the transport; normalize before echoing the RPC response.
162- const payload = res . payloadJSON ? safeParseJson ( res . payloadJSON ) : res . payload ;
163- respond ( true , payload , undefined ) ;
170+ readPayload : ( res ) => ( res . payloadJSON ? safeParseJson ( res . payloadJSON ) : res . payload ) ,
164171 } ) ;
165172 } ,
166173 "exec.approvals.node.set" : async ( { params, respond, context } ) => {
167- if (
168- ! assertValidParams (
169- params ,
170- validateExecApprovalsNodeSetParams ,
171- "exec.approvals.node.set" ,
172- respond ,
173- )
174- ) {
175- return ;
176- }
177- const { nodeId, file, baseHash } = params as {
178- nodeId : string ;
179- file : ExecApprovalsFile ;
180- baseHash ?: string ;
181- } ;
182- const id = resolveNodeIdOrRespond ( nodeId , respond ) ;
183- if ( ! id ) {
184- return ;
185- }
186- await respondUnavailableOnThrow ( respond , async ( ) => {
187- const res = await context . nodeRegistry . invoke ( {
188- nodeId : id ,
189- command : "system.execApprovals.set" ,
190- params : { file, baseHash } ,
191- } ) ;
192- if ( ! respondUnavailableOnNodeInvokeError ( respond , res ) ) {
193- return ;
194- }
174+ await respondWithExecApprovalsNodePayload ( {
175+ method : "exec.approvals.node.set" ,
176+ rawParams : params ,
177+ validate : validateExecApprovalsNodeSetParams ,
178+ context,
179+ respond,
180+ command : "system.execApprovals.set" ,
181+ commandParams : ( parsedParams ) => ( {
182+ file : parsedParams . file ,
183+ baseHash : parsedParams . baseHash ,
184+ } ) ,
195185 // node.set returns JSON on the command channel; keep the gateway response
196186 // shape aligned with local exec.approvals.set.
197- const payload = safeParseJson ( res . payloadJSON ?? null ) ;
198- respond ( true , payload , undefined ) ;
187+ readPayload : ( res ) => safeParseJson ( res . payloadJSON ?? null ) ,
199188 } ) ;
200189 } ,
201190} ;
0 commit comments