@@ -10,7 +10,34 @@ const mcpNameHeader = 'X-mcp';
1010const jqHeader = 'X-jq' ;
1111const contentTypeHeader = 'Content-Type' ;
1212
13- // fetchApiServer is a wrapper around fetch that adds the necessary headers for the Crate API or the MCP API server.
13+ /**
14+ * Attempts to parse the response body as JSON. If parsing fails, returns the raw text.
15+ *
16+ * @param {Response } res - The fetch Response object.
17+ * @returns {Promise<unknown> } The parsed JSON object or the raw text if parsing fails.
18+ */
19+ export const parseJsonOrText = async ( res : Response ) : Promise < unknown > => {
20+ const text = await res . text ( ) ;
21+ try {
22+ return JSON . parse ( text ) ;
23+ } catch {
24+ return text ;
25+ }
26+ } ;
27+
28+ /**
29+ * Wrapper around fetch that adds the necessary headers for the Crate API or the MCP API server.
30+ * Handles authentication, content type, and custom headers for backend routing.
31+ * Redirects to login if the response is unauthorized (401).
32+ *
33+ * @param {string } path - The API endpoint path (appended to `/api/onboarding`).
34+ * @param {ApiConfig } config - The API configuration, including authentication and MCP/Crate context.
35+ * @param {string } [jq] - Optional jq transformation string for the proxy server.
36+ * @param {string } [httpMethod='GET'] - The HTTP method to use (GET, POST, PATCH, etc.).
37+ * @param {BodyInit } [body] - The request body, if applicable.
38+ * @returns {Promise<Response> } The fetch Response object.
39+ * @throws {APIError } Throws an APIError if the response is not ok.
40+ */
1441export const fetchApiServer = async (
1542 path : string ,
1643 config : ApiConfig ,
@@ -31,7 +58,7 @@ export const fetchApiServer = async (
3158 if ( jq ) headers [ jqHeader ] = jq ;
3259
3360 // If the config object has a mcpConfig, it is assumed that the request is for the MCP API server and the necessary headers are set for the backend to get the OIDC kubeconfig without exposing it to the frontend,
34- // otherwise, the useCrateClusterHeader is set to true to indicate that the request is for the Crate
61+ // otherwise, the useCrateClusterHeader is set to true to indicate that the request is for the Crate.
3562 if ( config . mcpConfig !== undefined ) {
3663 headers [ projectNameHeader ] = config . mcpConfig . projectName ;
3764 headers [ workspaceNameHeader ] = config . mcpConfig . workspaceName ;
@@ -48,18 +75,30 @@ export const fetchApiServer = async (
4875
4976 if ( ! res . ok ) {
5077 if ( res . status === 401 ) {
51- // Unauthorized (token expired), redirect to the login page
78+ // Unauthorized (token expired), redirect to the login page.
5279 sessionStorage . setItem ( AUTH_FLOW_SESSION_KEY , 'onboarding' ) ;
5380 window . location . replace ( `/api/auth/onboarding/login?redirectTo=${ encodeURIComponent ( getRedirectSuffix ( ) ) } ` ) ;
5481 }
5582 const error = new APIError ( 'An error occurred while fetching the data.' , res . status ) ;
56- error . info = await res . json ( ) ;
83+ error . info = await parseJsonOrText ( res ) ;
5784 throw error ;
5885 }
5986
6087 return res ;
6188} ;
6289
90+ /**
91+ * Calls fetchApiServer and parses the response as JSON.
92+ *
93+ * @template T
94+ * @param {string } path - The API endpoint path (appended to `/api/onboarding`).
95+ * @param {ApiConfig } config - The API configuration, including authentication and MCP/Crate context.
96+ * @param {string } [jq] - Optional jq transformation string for the proxy server.
97+ * @param {string } [httpMethod='GET'] - The HTTP method to use (GET, POST, PATCH, etc.).
98+ * @param {BodyInit } [body] - The request body, if applicable.
99+ * @returns {Promise<T> } The parsed JSON response.
100+ * @throws {APIError } Throws an APIError if the response is not ok.
101+ */
63102export const fetchApiServerJson = async < T > (
64103 path : string ,
65104 config : ApiConfig ,
@@ -71,15 +110,3 @@ export const fetchApiServerJson = async <T>(
71110
72111 return await res . json ( ) ;
73112} ;
74-
75- // request is of [path, config, jq]
76- export const fetchApiServerJsonMultiple = ( requests : [ string | null , ApiConfig , string | undefined ] [ ] ) => {
77- return Promise . all (
78- requests
79- . filter ( ( r ) => r [ 0 ] !== null )
80- . map ( ( [ path , config , jq ] ) =>
81- // @ts -expect-error path is not null
82- fetchApiServer ( path , config , jq ) . then ( ( res ) => res . json ( ) ) ,
83- ) ,
84- ) ;
85- } ;
0 commit comments