1- import { createServer } from "node:http" ;
1+ import { createServer , type ServerResponse } from "node:http" ;
22import { fileURLToPath } from "node:url" ;
33
44import { dispatchJsonRpc } from "./json-rpc.ts" ;
@@ -9,6 +9,22 @@ interface ServerOptions {
99 port : number ;
1010}
1111
12+ const jsonHeaders = {
13+ "access-control-allow-headers" : "content-type" ,
14+ "access-control-allow-methods" : "GET,POST,OPTIONS" ,
15+ "access-control-allow-origin" : "*" ,
16+ "content-type" : "application/json" ,
17+ } ;
18+
19+ function jsonResult ( response : ReturnType < typeof dispatchJsonRpc > ) : unknown {
20+ return Array . isArray ( response ) ? response : response ?. result ?? response ;
21+ }
22+
23+ function writeJson ( res : ServerResponse , statusCode : number , body : unknown ) : void {
24+ res . writeHead ( statusCode , jsonHeaders ) ;
25+ res . end ( `${ JSON . stringify ( body ) } \n` ) ;
26+ }
27+
1228function parseArgs ( args : string [ ] ) : ServerOptions {
1329 const options : ServerOptions = {
1430 host : "127.0.0.1" ,
@@ -44,16 +60,26 @@ function parseArgs(args: string[]): ServerOptions {
4460export function startControlPlaneServer ( options : ServerOptions ) : ReturnType < typeof createServer > {
4561 const state = loadControlPlaneState ( ) ;
4662 const server = createServer ( ( req , res ) => {
63+ if ( req . method === "OPTIONS" ) {
64+ res . writeHead ( 204 , jsonHeaders ) ;
65+ res . end ( ) ;
66+ return ;
67+ }
68+
4769 if ( req . method === "GET" && req . url === "/health" ) {
4870 const response = dispatchJsonRpc ( { jsonrpc : "2.0" , id : "health" , method : "health" } , { state } ) ;
49- res . writeHead ( 200 , { "content-type" : "application/json" } ) ;
50- res . end ( `${ JSON . stringify ( Array . isArray ( response ) ? response : response ?. result ?? response ) } \n` ) ;
71+ writeJson ( res , 200 , jsonResult ( response ) ) ;
72+ return ;
73+ }
74+
75+ if ( req . method === "GET" && req . url === "/state" ) {
76+ const response = dispatchJsonRpc ( { jsonrpc : "2.0" , id : "state" , method : "devnet_state" } , { state } ) ;
77+ writeJson ( res , 200 , jsonResult ( response ) ) ;
5178 return ;
5279 }
5380
5481 if ( req . method !== "POST" || req . url !== "/rpc" ) {
55- res . writeHead ( 404 , { "content-type" : "application/json" } ) ;
56- res . end ( JSON . stringify ( { error : "not found" } ) ) ;
82+ writeJson ( res , 404 , { error : "not found" } ) ;
5783 return ;
5884 }
5985
@@ -67,15 +93,13 @@ export function startControlPlaneServer(options: ServerOptions): ReturnType<type
6793 const payload = JSON . parse ( body ) as unknown ;
6894 const response = dispatchJsonRpc ( payload , { state } ) ;
6995 if ( response === undefined ) {
70- res . writeHead ( 204 ) ;
96+ res . writeHead ( 204 , jsonHeaders ) ;
7197 res . end ( ) ;
7298 return ;
7399 }
74- res . writeHead ( 200 , { "content-type" : "application/json" } ) ;
75- res . end ( `${ JSON . stringify ( response ) } \n` ) ;
100+ writeJson ( res , 200 , response ) ;
76101 } catch ( error ) {
77- res . writeHead ( 400 , { "content-type" : "application/json" } ) ;
78- res . end ( JSON . stringify ( {
102+ writeJson ( res , 400 , {
79103 jsonrpc : "2.0" ,
80104 id : null ,
81105 error : {
@@ -87,7 +111,7 @@ export function startControlPlaneServer(options: ServerOptions): ReturnType<type
87111 localOnly : true ,
88112 } ,
89113 } ,
90- } ) ) ;
114+ } ) ;
91115 }
92116 } ) ;
93117 } ) ;
0 commit comments