refactor(client): unwrap .data from TransformHttpResponseInterceptor
The server-side TransformHttpResponseInterceptor wraps every body in
{ data, success, status }. The axios interceptor only unwraps the
transport layer, so calls return that envelope object — read .data
to get the actual payload.
Aligns the remaining Acadenice REST clients (backlinks, clipper,
slash-commands, sync-blocks, templates, graph, rbac) with the
existing convention and drops a few hardcoded /api/v1 prefixes that
duplicated the api baseURL.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
843986d5c2
commit
47dee1eb12
7 changed files with 101 additions and 102 deletions
|
|
@ -28,7 +28,7 @@ export interface BacklinksResult {
|
|||
|
||||
async function fetchBacklinks(pageId: string): Promise<BacklinksResult> {
|
||||
const res = await api.get<BacklinksResult>(
|
||||
`/acadenice/pages/${pageId}/backlinks`,
|
||||
`/v1/pages/${pageId}/backlinks`,
|
||||
);
|
||||
return res.data;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
import axios from 'axios';
|
||||
import api from '@/lib/api-client';
|
||||
|
||||
const BASE = '/api/v1/clipper';
|
||||
const BASE = '/v1/clipper';
|
||||
|
||||
export interface ClipperTokenInfo {
|
||||
id: string;
|
||||
|
|
@ -23,17 +23,17 @@ export interface CreateTokenResponse {
|
|||
}
|
||||
|
||||
export const clipperClient = {
|
||||
listTokens(): Promise<ClipperTokenInfo[]> {
|
||||
return axios.get<ClipperTokenInfo[]>(`${BASE}/tokens`).then((r) => r.data);
|
||||
async listTokens(): Promise<ClipperTokenInfo[]> {
|
||||
const r = await api.get<ClipperTokenInfo[]>(`${BASE}/tokens`);
|
||||
return r.data;
|
||||
},
|
||||
|
||||
createToken(payload: CreateTokenPayload): Promise<CreateTokenResponse> {
|
||||
return axios
|
||||
.post<CreateTokenResponse>(`${BASE}/tokens`, payload)
|
||||
.then((r) => r.data);
|
||||
async createToken(payload: CreateTokenPayload): Promise<CreateTokenResponse> {
|
||||
const r = await api.post<CreateTokenResponse>(`${BASE}/tokens`, payload);
|
||||
return r.data;
|
||||
},
|
||||
|
||||
revokeToken(tokenId: string): Promise<void> {
|
||||
return axios.delete(`${BASE}/tokens/${tokenId}`).then(() => undefined);
|
||||
async revokeToken(tokenId: string): Promise<void> {
|
||||
await api.delete(`${BASE}/tokens/${tokenId}`);
|
||||
},
|
||||
};
|
||||
|
|
|
|||
|
|
@ -69,5 +69,6 @@ export async function fetchGraph(
|
|||
const qs = new URLSearchParams(query).toString();
|
||||
const url = qs ? `/v1/graph?${qs}` : "/v1/graph";
|
||||
|
||||
return api.get(url) as unknown as Promise<GraphResponse>;
|
||||
const r = await api.get<GraphResponse>(url);
|
||||
return r.data;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -9,57 +9,44 @@ import {
|
|||
IMyPermissionsResponse,
|
||||
} from "@/features/acadenice/rbac/types/rbac.types";
|
||||
|
||||
/**
|
||||
* REST client for the Acadenice RBAC API (R2.1 backend).
|
||||
* Endpoints under /api/v1 — relative to api.baseURL ("/api").
|
||||
*
|
||||
* Note : Docmost's axios interceptor returns `response.data` directly, so the
|
||||
* return value of `api.get(...)` is already the body payload.
|
||||
*/
|
||||
// The global `TransformHttpResponseInterceptor` wraps every body in
|
||||
// `{ data, success, status }`. The axios interceptor already unwraps the
|
||||
// transport layer, so each call returns that wrap object — we read `.data`
|
||||
// to get the actual payload.
|
||||
|
||||
export async function getPermissionsCatalog(): Promise<IPermissionDescriptor[]> {
|
||||
return api.get("/v1/permissions") as unknown as Promise<
|
||||
IPermissionDescriptor[]
|
||||
>;
|
||||
const r = await api.get<IPermissionDescriptor[]>("/v1/permissions");
|
||||
return r.data;
|
||||
}
|
||||
|
||||
/**
|
||||
* Fetches the effective permissions of the authenticated user in the current
|
||||
* workspace. Backed by the Redis 60s cache server-side (R2.1).
|
||||
*/
|
||||
export async function getMyPermissions(): Promise<IMyPermissionsResponse> {
|
||||
return api.get(
|
||||
"/v1/permissions/me",
|
||||
) as unknown as Promise<IMyPermissionsResponse>;
|
||||
const r = await api.get<IMyPermissionsResponse>("/v1/permissions/me");
|
||||
return r.data;
|
||||
}
|
||||
|
||||
export async function listRoles(): Promise<IRole[]> {
|
||||
return api.get("/v1/roles") as unknown as Promise<IRole[]>;
|
||||
const r = await api.get<IRole[]>("/v1/roles");
|
||||
return r.data;
|
||||
}
|
||||
|
||||
export async function getRole(roleId: string): Promise<IRoleWithPermissions> {
|
||||
return api.get(
|
||||
`/v1/roles/${roleId}`,
|
||||
) as unknown as Promise<IRoleWithPermissions>;
|
||||
const r = await api.get<IRoleWithPermissions>(`/v1/roles/${roleId}`);
|
||||
return r.data;
|
||||
}
|
||||
|
||||
export async function createRole(
|
||||
payload: ICreateRolePayload,
|
||||
): Promise<IRoleWithPermissions> {
|
||||
return api.post(
|
||||
"/v1/roles",
|
||||
payload,
|
||||
) as unknown as Promise<IRoleWithPermissions>;
|
||||
const r = await api.post<IRoleWithPermissions>("/v1/roles", payload);
|
||||
return r.data;
|
||||
}
|
||||
|
||||
export async function updateRole(
|
||||
roleId: string,
|
||||
payload: IUpdateRolePayload,
|
||||
): Promise<IRole> {
|
||||
return api.patch(
|
||||
`/v1/roles/${roleId}`,
|
||||
payload,
|
||||
) as unknown as Promise<IRole>;
|
||||
const r = await api.patch<IRole>(`/v1/roles/${roleId}`, payload);
|
||||
return r.data;
|
||||
}
|
||||
|
||||
export async function deleteRole(roleId: string): Promise<void> {
|
||||
|
|
@ -70,26 +57,30 @@ export async function setRolePermissions(
|
|||
roleId: string,
|
||||
permissions: string[],
|
||||
): Promise<IRoleWithPermissions> {
|
||||
return api.put(`/v1/roles/${roleId}/permissions`, {
|
||||
permissions,
|
||||
}) as unknown as Promise<IRoleWithPermissions>;
|
||||
const r = await api.put<IRoleWithPermissions>(
|
||||
`/v1/roles/${roleId}/permissions`,
|
||||
{ permissions },
|
||||
);
|
||||
return r.data;
|
||||
}
|
||||
|
||||
export async function listUserRoles(
|
||||
userId: string,
|
||||
): Promise<IUserRoleAssignment[]> {
|
||||
return api.get(`/v1/users/${userId}/roles`) as unknown as Promise<
|
||||
IUserRoleAssignment[]
|
||||
>;
|
||||
const r = await api.get<IUserRoleAssignment[]>(
|
||||
`/v1/users/${userId}/roles`,
|
||||
);
|
||||
return r.data;
|
||||
}
|
||||
|
||||
export async function assignRolesToUser(
|
||||
userId: string,
|
||||
roleIds: string[],
|
||||
): Promise<{ ok: true }> {
|
||||
return api.post(`/v1/users/${userId}/roles`, {
|
||||
const r = await api.post<{ ok: true }>(`/v1/users/${userId}/roles`, {
|
||||
roleIds,
|
||||
}) as unknown as Promise<{ ok: true }>;
|
||||
});
|
||||
return r.data;
|
||||
}
|
||||
|
||||
export async function unassignRoleFromUser(
|
||||
|
|
|
|||
|
|
@ -1,7 +1,4 @@
|
|||
import axios from 'axios';
|
||||
|
||||
// Re-use the same axios instance that Docmost uses for authenticated requests.
|
||||
// The `withCredentials` is handled globally by the Docmost axios setup.
|
||||
import api from '@/lib/api-client';
|
||||
|
||||
export interface SlashCommandDto {
|
||||
id: string;
|
||||
|
|
@ -35,34 +32,35 @@ export interface CreateSlashCommandPayload {
|
|||
|
||||
export type UpdateSlashCommandPayload = Partial<CreateSlashCommandPayload>;
|
||||
|
||||
const BASE = '/api/v1/slash-commands';
|
||||
const BASE = '/v1/slash-commands';
|
||||
|
||||
export const slashCommandsClient = {
|
||||
list(): Promise<SlashCommandDto[]> {
|
||||
return axios.get<SlashCommandDto[]>(BASE).then((r) => r.data);
|
||||
async list(): Promise<SlashCommandDto[]> {
|
||||
const r = await api.get<SlashCommandDto[]>(BASE);
|
||||
return r.data;
|
||||
},
|
||||
|
||||
get(id: string): Promise<SlashCommandDto> {
|
||||
return axios.get<SlashCommandDto>(`${BASE}/${id}`).then((r) => r.data);
|
||||
async get(id: string): Promise<SlashCommandDto> {
|
||||
const r = await api.get<SlashCommandDto>(`${BASE}/${id}`);
|
||||
return r.data;
|
||||
},
|
||||
|
||||
create(payload: CreateSlashCommandPayload): Promise<SlashCommandDto> {
|
||||
return axios.post<SlashCommandDto>(BASE, payload).then((r) => r.data);
|
||||
async create(payload: CreateSlashCommandPayload): Promise<SlashCommandDto> {
|
||||
const r = await api.post<SlashCommandDto>(BASE, payload);
|
||||
return r.data;
|
||||
},
|
||||
|
||||
update(id: string, payload: UpdateSlashCommandPayload): Promise<SlashCommandDto> {
|
||||
return axios
|
||||
.patch<SlashCommandDto>(`${BASE}/${id}`, payload)
|
||||
.then((r) => r.data);
|
||||
async update(id: string, payload: UpdateSlashCommandPayload): Promise<SlashCommandDto> {
|
||||
const r = await api.patch<SlashCommandDto>(`${BASE}/${id}`, payload);
|
||||
return r.data;
|
||||
},
|
||||
|
||||
delete(id: string): Promise<void> {
|
||||
return axios.delete(`${BASE}/${id}`).then(() => undefined);
|
||||
async delete(id: string): Promise<void> {
|
||||
await api.delete(`${BASE}/${id}`);
|
||||
},
|
||||
|
||||
toggle(id: string, isEnabled: boolean): Promise<SlashCommandDto> {
|
||||
return axios
|
||||
.patch<SlashCommandDto>(`${BASE}/${id}`, { isEnabled })
|
||||
.then((r) => r.data);
|
||||
async toggle(id: string, isEnabled: boolean): Promise<SlashCommandDto> {
|
||||
const r = await api.patch<SlashCommandDto>(`${BASE}/${id}`, { isEnabled });
|
||||
return r.data;
|
||||
},
|
||||
};
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
import axios from 'axios';
|
||||
import api from '@/lib/api-client';
|
||||
|
||||
export interface SyncBlockDto {
|
||||
id: string;
|
||||
|
|
@ -17,26 +17,30 @@ export interface SyncBlockUsageDto {
|
|||
workspaceId: string;
|
||||
}
|
||||
|
||||
const BASE = '/api/v1/sync-blocks';
|
||||
const BASE = '/v1/sync-blocks';
|
||||
|
||||
export const syncBlocksClient = {
|
||||
create(content: Record<string, unknown> = {}): Promise<SyncBlockDto> {
|
||||
return axios.post<SyncBlockDto>(BASE, { content }).then((r) => r.data);
|
||||
async create(content: Record<string, unknown> = {}): Promise<SyncBlockDto> {
|
||||
const r = await api.post<SyncBlockDto>(BASE, { content });
|
||||
return r.data;
|
||||
},
|
||||
|
||||
get(id: string): Promise<SyncBlockDto> {
|
||||
return axios.get<SyncBlockDto>(`${BASE}/${id}`).then((r) => r.data);
|
||||
async get(id: string): Promise<SyncBlockDto> {
|
||||
const r = await api.get<SyncBlockDto>(`${BASE}/${id}`);
|
||||
return r.data;
|
||||
},
|
||||
|
||||
update(id: string, content: Record<string, unknown>): Promise<SyncBlockDto> {
|
||||
return axios.patch<SyncBlockDto>(`${BASE}/${id}`, { content }).then((r) => r.data);
|
||||
async update(id: string, content: Record<string, unknown>): Promise<SyncBlockDto> {
|
||||
const r = await api.patch<SyncBlockDto>(`${BASE}/${id}`, { content });
|
||||
return r.data;
|
||||
},
|
||||
|
||||
delete(id: string): Promise<void> {
|
||||
return axios.delete(`${BASE}/${id}`).then(() => undefined);
|
||||
async delete(id: string): Promise<void> {
|
||||
await api.delete(`${BASE}/${id}`);
|
||||
},
|
||||
|
||||
usages(id: string): Promise<SyncBlockUsageDto[]> {
|
||||
return axios.get<SyncBlockUsageDto[]>(`${BASE}/${id}/usages`).then((r) => r.data);
|
||||
async usages(id: string): Promise<SyncBlockUsageDto[]> {
|
||||
const r = await api.get<SyncBlockUsageDto[]>(`${BASE}/${id}/usages`);
|
||||
return r.data;
|
||||
},
|
||||
};
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
import axios from 'axios';
|
||||
import api from '@/lib/api-client';
|
||||
|
||||
export interface TemplateDto {
|
||||
id: string;
|
||||
|
|
@ -36,41 +36,46 @@ export interface InstantiatePayload {
|
|||
name?: string;
|
||||
}
|
||||
|
||||
const BASE = '/api/v1/templates';
|
||||
const BASE = '/v1/templates';
|
||||
|
||||
export const templatesClient = {
|
||||
list(opts: { category?: string; search?: string } = {}): Promise<TemplateDto[]> {
|
||||
return axios
|
||||
.get<TemplateDto[]>(BASE, { params: opts })
|
||||
.then((r) => r.data);
|
||||
async list(opts: { category?: string; search?: string } = {}): Promise<TemplateDto[]> {
|
||||
const r = await api.get<TemplateDto[]>(BASE, { params: opts });
|
||||
return r.data;
|
||||
},
|
||||
|
||||
get(id: string): Promise<TemplateDto> {
|
||||
return axios.get<TemplateDto>(`${BASE}/${id}`).then((r) => r.data);
|
||||
async get(id: string): Promise<TemplateDto> {
|
||||
const r = await api.get<TemplateDto>(`${BASE}/${id}`);
|
||||
return r.data;
|
||||
},
|
||||
|
||||
create(payload: CreateTemplatePayload): Promise<TemplateDto> {
|
||||
return axios.post<TemplateDto>(BASE, payload).then((r) => r.data);
|
||||
async create(payload: CreateTemplatePayload): Promise<TemplateDto> {
|
||||
const r = await api.post<TemplateDto>(BASE, payload);
|
||||
return r.data;
|
||||
},
|
||||
|
||||
update(id: string, payload: UpdateTemplatePayload): Promise<TemplateDto> {
|
||||
return axios.patch<TemplateDto>(`${BASE}/${id}`, payload).then((r) => r.data);
|
||||
async update(id: string, payload: UpdateTemplatePayload): Promise<TemplateDto> {
|
||||
const r = await api.patch<TemplateDto>(`${BASE}/${id}`, payload);
|
||||
return r.data;
|
||||
},
|
||||
|
||||
delete(id: string): Promise<void> {
|
||||
return axios.delete(`${BASE}/${id}`).then(() => undefined);
|
||||
async delete(id: string): Promise<void> {
|
||||
await api.delete(`${BASE}/${id}`);
|
||||
},
|
||||
|
||||
instantiate(
|
||||
async instantiate(
|
||||
id: string,
|
||||
payload: InstantiatePayload,
|
||||
): Promise<{ pageId: string; slugId: string }> {
|
||||
return axios
|
||||
.post<{ pageId: string; slugId: string }>(`${BASE}/${id}/instantiate`, payload)
|
||||
.then((r) => r.data);
|
||||
const r = await api.post<{ pageId: string; slugId: string }>(
|
||||
`${BASE}/${id}/instantiate`,
|
||||
payload,
|
||||
);
|
||||
return r.data;
|
||||
},
|
||||
|
||||
setDefault(id: string): Promise<TemplateDto> {
|
||||
return axios.patch<TemplateDto>(`${BASE}/${id}/default`).then((r) => r.data);
|
||||
async setDefault(id: string): Promise<TemplateDto> {
|
||||
const r = await api.patch<TemplateDto>(`${BASE}/${id}/default`);
|
||||
return r.data;
|
||||
},
|
||||
};
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue