feat(ws): Refactor restYAML to restFILE (#478)

Signed-off-by: Charles Thao <cthao@redhat.com>
This commit is contained in:
Charles Thao 2025-07-17 09:53:40 -04:00 committed by Bhakti Narvekar
parent 0e90e5da65
commit 3e7f44a7ae
4 changed files with 18 additions and 52 deletions

View File

@ -80,7 +80,7 @@ export const WorkspaceKindForm: React.FC = () => {
// TODO: Complete handleCreate with API call to create a new WS kind
try {
if (mode === 'create') {
const newWorkspaceKind = await api.createWorkspaceKind({}, yamlValue);
const newWorkspaceKind = await api.createWorkspaceKind({ directYAML: true }, yamlValue);
// TODO: alert user about success
console.info('New workspace kind created:', JSON.stringify(newWorkspaceKind));
navigate('workspaceKinds');

View File

@ -19,6 +19,7 @@ export const mergeRequestInit = (
type CallRestJSONOptions = {
queryParams?: Record<string, unknown>;
parseJSON?: boolean;
directYAML?: boolean;
} & EitherOrNone<
{
fileContents: string;
@ -32,7 +33,7 @@ const callRestJSON = <T>(
host: string,
path: string,
requestInit: RequestInit,
{ data, fileContents, queryParams, parseJSON = true }: CallRestJSONOptions,
{ data, fileContents, queryParams, parseJSON = true, directYAML = false }: CallRestJSONOptions,
): Promise<T> => {
const { method, ...otherOptions } = requestInit;
@ -54,12 +55,17 @@ const callRestJSON = <T>(
let contentType: string | undefined;
let formData: FormData | undefined;
if (fileContents) {
formData = new FormData();
formData.append(
'uploadfile',
new Blob([fileContents], { type: 'application/x-yaml' }),
'uploadedFile.yml',
);
if (directYAML) {
requestData = fileContents;
contentType = 'application/yaml';
} else {
formData = new FormData();
formData.append(
'uploadfile',
new Blob([fileContents], { type: 'application/x-yaml' }),
'uploadedFile.yml',
);
}
} else if (data) {
// It's OK for contentType and requestData to BOTH be undefined for e.g. a GET request or POST with no body.
contentType = 'application/json;charset=UTF-8';
@ -122,6 +128,7 @@ export const restFILE = <T>(
fileContents,
queryParams,
parseJSON: options?.parseJSON,
directYAML: options?.directYAML,
});
/** POST -- but no body data -- targets simple endpoints */
@ -173,48 +180,6 @@ export const restDELETE = <T>(
parseJSON: options?.parseJSON,
});
/** POST -- but with YAML content directly in body */
export const restYAML = <T>(
host: string,
path: string,
yamlContent: string,
queryParams?: Record<string, unknown>,
options?: APIOptions,
): Promise<T> => {
const { method, ...otherOptions } = mergeRequestInit(options, { method: 'POST' });
const sanitizedQueryParams = queryParams
? Object.entries(queryParams).reduce((acc, [key, value]) => {
if (value) {
return { ...acc, [key]: value };
}
return acc;
}, {})
: null;
const searchParams = sanitizedQueryParams
? new URLSearchParams(sanitizedQueryParams).toString()
: null;
return fetch(`${host}${path}${searchParams ? `?${searchParams}` : ''}`, {
...otherOptions,
headers: {
...otherOptions.headers,
...(DEV_MODE && { [AUTH_HEADER]: localStorage.getItem(AUTH_HEADER) }),
'Content-Type': 'application/vnd.kubeflow-notebooks.manifest+yaml',
},
method,
body: yamlContent,
}).then((response) =>
response.text().then((fetchedData) => {
if (options?.parseJSON !== false) {
return JSON.parse(fetchedData);
}
return fetchedData;
}),
);
};
export const isNotebookResponse = <T>(response: unknown): response is ResponseBody<T> => {
if (typeof response === 'object' && response !== null) {
// eslint-disable-next-line @typescript-eslint/consistent-type-assertions

View File

@ -1,10 +1,10 @@
import {
restCREATE,
restDELETE,
restFILE,
restGET,
restPATCH,
restUPDATE,
restYAML,
wrapRequest,
} from '~/shared/api/apiUtils';
import {
@ -72,7 +72,7 @@ export const getWorkspaceKind: GetWorkspaceKindAPI = (hostPath) => (opts, kind)
wrapRequest(restGET(hostPath, `/workspacekinds/${kind}`, {}, opts));
export const createWorkspaceKind: CreateWorkspaceKindAPI = (hostPath) => (opts, data) =>
wrapRequest(restYAML(hostPath, `/workspacekinds`, data, {}, opts));
wrapRequest(restFILE(hostPath, `/workspacekinds`, data, {}, opts));
export const updateWorkspaceKind: UpdateWorkspaceKindAPI = (hostPath) => (opts, kind, data) =>
wrapRequest(restUPDATE(hostPath, `/workspacekinds/${kind}`, data, {}, opts));

View File

@ -3,6 +3,7 @@ export type APIOptions = {
signal?: AbortSignal;
parseJSON?: boolean;
headers?: Record<string, string>;
directYAML?: boolean;
};
export type APIState<T> = {