feat(react-openapi): add patch operation support
- Add patch to ResourceConfig.operations type - Separate PUT and PATCH detection in resource-config transformer - update() now always calls PUT; new patch() method available conditionally when spec defines PATCH
This commit is contained in:
@@ -56,6 +56,7 @@ interface UseResourceReturn {
|
||||
get: (id: string | number, params?: Record<string, any>) => Promise<any>;
|
||||
create: (data: any) => Promise<any>;
|
||||
update: (id: string | number, data: any) => Promise<any>;
|
||||
patch?: (id: string | number, data: any) => Promise<any>;
|
||||
remove: (id: string | number) => Promise<void>;
|
||||
stream?: (handlers: StreamHandlers, pathParams?: Record<string, string | number>) => StreamSubscription;
|
||||
loading: boolean;
|
||||
@@ -596,7 +597,7 @@ export function useResource(resourceName: string): UseResourceReturn {
|
||||
|
||||
const rPath = resource?.path;
|
||||
const rPagination = resource?.pagination;
|
||||
const rUpdateMethod = resource?.updateMethod;
|
||||
const rPatch = resource ? (resource.operations.patch || undefined) : false;
|
||||
const rStreaming = resource?.streaming;
|
||||
const rFields = resource?.fields;
|
||||
|
||||
@@ -706,8 +707,7 @@ export function useResource(resourceName: string): UseResourceReturn {
|
||||
const sanitized = rFields && schemas
|
||||
? await sanitizePayload(data, rFields, schemas, resolveFk)
|
||||
: data;
|
||||
const method = rUpdateMethod ?? "put";
|
||||
const res = await (method === "patch" ? api.patch : api.put)(`${rPath}/${id}`, sanitized);
|
||||
const res = await api.put(`${rPath}/${id}`, sanitized);
|
||||
return res.data;
|
||||
} catch (e: any) {
|
||||
setError(parseError(e));
|
||||
@@ -716,7 +716,29 @@ export function useResource(resourceName: string): UseResourceReturn {
|
||||
setLoading(false);
|
||||
}
|
||||
},
|
||||
[rPath, rFields, schemas, resolveFk, rUpdateMethod, setLoading, setError]
|
||||
[rPath, rFields, schemas, resolveFk, setLoading, setError]
|
||||
);
|
||||
|
||||
const _patch = useCallback(
|
||||
async (id: string | number, data: any): Promise<any> => {
|
||||
if (!rPath) throw new Error(`Resource "${resourceName}" not found yet`);
|
||||
setLoading(true);
|
||||
setError(null);
|
||||
try {
|
||||
const api = getApi();
|
||||
const sanitized = rFields && schemas
|
||||
? await sanitizePayload(data, rFields, schemas, resolveFk)
|
||||
: data;
|
||||
const res = await api.patch(`${rPath}/${id}`, sanitized);
|
||||
return res.data;
|
||||
} catch (e: any) {
|
||||
setError(parseError(e));
|
||||
throw e;
|
||||
} finally {
|
||||
setLoading(false);
|
||||
}
|
||||
},
|
||||
[rPath, rFields, schemas, resolveFk, setLoading, setError]
|
||||
);
|
||||
|
||||
const remove = useCallback(
|
||||
@@ -791,6 +813,7 @@ export function useResource(resourceName: string): UseResourceReturn {
|
||||
get,
|
||||
create,
|
||||
update,
|
||||
patch: undefined,
|
||||
remove,
|
||||
stream: undefined,
|
||||
loading: false,
|
||||
@@ -798,5 +821,5 @@ export function useResource(resourceName: string): UseResourceReturn {
|
||||
};
|
||||
}
|
||||
|
||||
return { resource, components, list, get, create, update, remove, stream: rStreaming ? stream : undefined, loading: state.loading, error: state.error };
|
||||
return { resource, components, list, get, create, update, patch: rPatch ? _patch : undefined, remove, stream: rStreaming ? stream : undefined, loading: state.loading, error: state.error };
|
||||
}
|
||||
@@ -98,9 +98,9 @@ export function buildResourceConfigs(spec: OpenApiSpec): ResourceConfig[] {
|
||||
const parent = nameMap.get(parentName);
|
||||
if (!parent) continue;
|
||||
if (hasOperation(pathObj, "get")) parent.operations.get = true;
|
||||
if (hasOperation(pathObj, "put") || hasOperation(pathObj, "patch")) parent.operations.update = true;
|
||||
if (hasOperation(pathObj, "put")) parent.operations.update = true;
|
||||
if (hasOperation(pathObj, "patch")) parent.operations.patch = true;
|
||||
if (hasOperation(pathObj, "delete")) parent.operations.delete = true;
|
||||
if (hasOperation(pathObj, "patch") && !hasOperation(pathObj, "put")) parent.updateMethod = "patch";
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -127,8 +127,8 @@ export function buildResourceConfigs(spec: OpenApiSpec): ResourceConfig[] {
|
||||
fields: hasSSE ? [SSE_RECEIVED_FIELD, ...fields.map((f) => ({ ...f, readOnly: true }))] : fields,
|
||||
orderedFields: [],
|
||||
operations: hasSSE
|
||||
? { list: true, get: false, create: false, update: false, delete: false }
|
||||
: { list: hasOperation(pathObj, "get"), get: false, create: false, update: false, delete: false },
|
||||
? { list: true, get: false, create: false, update: false, patch: false, delete: false }
|
||||
: { list: hasOperation(pathObj, "get"), get: false, create: false, update: false, patch: false, delete: false },
|
||||
updateMethod: "put",
|
||||
pagination: hasSSE ? null : detectPagination(pathObj),
|
||||
relationships: [],
|
||||
@@ -172,9 +172,9 @@ export function buildResourceConfigs(spec: OpenApiSpec): ResourceConfig[] {
|
||||
listColumns: schema?.["x-list-columns"] ?? [],
|
||||
fields: hasSSE ? [SSE_RECEIVED_FIELD, ...fields.map((f) => ({ ...f, readOnly: true }))] : fields,
|
||||
orderedFields: [],
|
||||
operations: hasSSE
|
||||
? { list: true, get: false, create: false, update: false, delete: false }
|
||||
: { list: hasOperation(pathObj, "get"), get: false, create: hasOperation(pathObj, "post"), update: false, delete: false },
|
||||
operations: hasSSE
|
||||
? { list: true, get: false, create: false, update: false, patch: false, delete: false }
|
||||
: { list: hasOperation(pathObj, "get"), get: false, create: hasOperation(pathObj, "post"), update: false, patch: false, delete: false },
|
||||
updateMethod: "put",
|
||||
pagination: hasSSE ? null : detectPagination(pathObj),
|
||||
relationships,
|
||||
|
||||
@@ -65,6 +65,7 @@ export interface ResourceConfig {
|
||||
get: boolean;
|
||||
create: boolean;
|
||||
update: boolean;
|
||||
patch: boolean;
|
||||
delete: boolean;
|
||||
};
|
||||
updateMethod: "put" | "patch";
|
||||
|
||||
Reference in New Issue
Block a user