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> {
|
async function fetchBacklinks(pageId: string): Promise<BacklinksResult> {
|
||||||
const res = await api.get<BacklinksResult>(
|
const res = await api.get<BacklinksResult>(
|
||||||
`/acadenice/pages/${pageId}/backlinks`,
|
`/v1/pages/${pageId}/backlinks`,
|
||||||
);
|
);
|
||||||
return res.data;
|
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 {
|
export interface ClipperTokenInfo {
|
||||||
id: string;
|
id: string;
|
||||||
|
|
@ -23,17 +23,17 @@ export interface CreateTokenResponse {
|
||||||
}
|
}
|
||||||
|
|
||||||
export const clipperClient = {
|
export const clipperClient = {
|
||||||
listTokens(): Promise<ClipperTokenInfo[]> {
|
async listTokens(): Promise<ClipperTokenInfo[]> {
|
||||||
return axios.get<ClipperTokenInfo[]>(`${BASE}/tokens`).then((r) => r.data);
|
const r = await api.get<ClipperTokenInfo[]>(`${BASE}/tokens`);
|
||||||
|
return r.data;
|
||||||
},
|
},
|
||||||
|
|
||||||
createToken(payload: CreateTokenPayload): Promise<CreateTokenResponse> {
|
async createToken(payload: CreateTokenPayload): Promise<CreateTokenResponse> {
|
||||||
return axios
|
const r = await api.post<CreateTokenResponse>(`${BASE}/tokens`, payload);
|
||||||
.post<CreateTokenResponse>(`${BASE}/tokens`, payload)
|
return r.data;
|
||||||
.then((r) => r.data);
|
|
||||||
},
|
},
|
||||||
|
|
||||||
revokeToken(tokenId: string): Promise<void> {
|
async revokeToken(tokenId: string): Promise<void> {
|
||||||
return axios.delete(`${BASE}/tokens/${tokenId}`).then(() => undefined);
|
await api.delete(`${BASE}/tokens/${tokenId}`);
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -69,5 +69,6 @@ export async function fetchGraph(
|
||||||
const qs = new URLSearchParams(query).toString();
|
const qs = new URLSearchParams(query).toString();
|
||||||
const url = qs ? `/v1/graph?${qs}` : "/v1/graph";
|
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,
|
IMyPermissionsResponse,
|
||||||
} from "@/features/acadenice/rbac/types/rbac.types";
|
} from "@/features/acadenice/rbac/types/rbac.types";
|
||||||
|
|
||||||
/**
|
// The global `TransformHttpResponseInterceptor` wraps every body in
|
||||||
* REST client for the Acadenice RBAC API (R2.1 backend).
|
// `{ data, success, status }`. The axios interceptor already unwraps the
|
||||||
* Endpoints under /api/v1 — relative to api.baseURL ("/api").
|
// transport layer, so each call returns that wrap object — we read `.data`
|
||||||
*
|
// to get the actual payload.
|
||||||
* Note : Docmost's axios interceptor returns `response.data` directly, so the
|
|
||||||
* return value of `api.get(...)` is already the body payload.
|
|
||||||
*/
|
|
||||||
|
|
||||||
export async function getPermissionsCatalog(): Promise<IPermissionDescriptor[]> {
|
export async function getPermissionsCatalog(): Promise<IPermissionDescriptor[]> {
|
||||||
return api.get("/v1/permissions") as unknown as Promise<
|
const r = await api.get<IPermissionDescriptor[]>("/v1/permissions");
|
||||||
IPermissionDescriptor[]
|
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> {
|
export async function getMyPermissions(): Promise<IMyPermissionsResponse> {
|
||||||
return api.get(
|
const r = await api.get<IMyPermissionsResponse>("/v1/permissions/me");
|
||||||
"/v1/permissions/me",
|
return r.data;
|
||||||
) as unknown as Promise<IMyPermissionsResponse>;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function listRoles(): Promise<IRole[]> {
|
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> {
|
export async function getRole(roleId: string): Promise<IRoleWithPermissions> {
|
||||||
return api.get(
|
const r = await api.get<IRoleWithPermissions>(`/v1/roles/${roleId}`);
|
||||||
`/v1/roles/${roleId}`,
|
return r.data;
|
||||||
) as unknown as Promise<IRoleWithPermissions>;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function createRole(
|
export async function createRole(
|
||||||
payload: ICreateRolePayload,
|
payload: ICreateRolePayload,
|
||||||
): Promise<IRoleWithPermissions> {
|
): Promise<IRoleWithPermissions> {
|
||||||
return api.post(
|
const r = await api.post<IRoleWithPermissions>("/v1/roles", payload);
|
||||||
"/v1/roles",
|
return r.data;
|
||||||
payload,
|
|
||||||
) as unknown as Promise<IRoleWithPermissions>;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function updateRole(
|
export async function updateRole(
|
||||||
roleId: string,
|
roleId: string,
|
||||||
payload: IUpdateRolePayload,
|
payload: IUpdateRolePayload,
|
||||||
): Promise<IRole> {
|
): Promise<IRole> {
|
||||||
return api.patch(
|
const r = await api.patch<IRole>(`/v1/roles/${roleId}`, payload);
|
||||||
`/v1/roles/${roleId}`,
|
return r.data;
|
||||||
payload,
|
|
||||||
) as unknown as Promise<IRole>;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function deleteRole(roleId: string): Promise<void> {
|
export async function deleteRole(roleId: string): Promise<void> {
|
||||||
|
|
@ -70,26 +57,30 @@ export async function setRolePermissions(
|
||||||
roleId: string,
|
roleId: string,
|
||||||
permissions: string[],
|
permissions: string[],
|
||||||
): Promise<IRoleWithPermissions> {
|
): Promise<IRoleWithPermissions> {
|
||||||
return api.put(`/v1/roles/${roleId}/permissions`, {
|
const r = await api.put<IRoleWithPermissions>(
|
||||||
permissions,
|
`/v1/roles/${roleId}/permissions`,
|
||||||
}) as unknown as Promise<IRoleWithPermissions>;
|
{ permissions },
|
||||||
|
);
|
||||||
|
return r.data;
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function listUserRoles(
|
export async function listUserRoles(
|
||||||
userId: string,
|
userId: string,
|
||||||
): Promise<IUserRoleAssignment[]> {
|
): Promise<IUserRoleAssignment[]> {
|
||||||
return api.get(`/v1/users/${userId}/roles`) as unknown as Promise<
|
const r = await api.get<IUserRoleAssignment[]>(
|
||||||
IUserRoleAssignment[]
|
`/v1/users/${userId}/roles`,
|
||||||
>;
|
);
|
||||||
|
return r.data;
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function assignRolesToUser(
|
export async function assignRolesToUser(
|
||||||
userId: string,
|
userId: string,
|
||||||
roleIds: string[],
|
roleIds: string[],
|
||||||
): Promise<{ ok: true }> {
|
): Promise<{ ok: true }> {
|
||||||
return api.post(`/v1/users/${userId}/roles`, {
|
const r = await api.post<{ ok: true }>(`/v1/users/${userId}/roles`, {
|
||||||
roleIds,
|
roleIds,
|
||||||
}) as unknown as Promise<{ ok: true }>;
|
});
|
||||||
|
return r.data;
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function unassignRoleFromUser(
|
export async function unassignRoleFromUser(
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,4 @@
|
||||||
import axios from 'axios';
|
import api from '@/lib/api-client';
|
||||||
|
|
||||||
// Re-use the same axios instance that Docmost uses for authenticated requests.
|
|
||||||
// The `withCredentials` is handled globally by the Docmost axios setup.
|
|
||||||
|
|
||||||
export interface SlashCommandDto {
|
export interface SlashCommandDto {
|
||||||
id: string;
|
id: string;
|
||||||
|
|
@ -35,34 +32,35 @@ export interface CreateSlashCommandPayload {
|
||||||
|
|
||||||
export type UpdateSlashCommandPayload = Partial<CreateSlashCommandPayload>;
|
export type UpdateSlashCommandPayload = Partial<CreateSlashCommandPayload>;
|
||||||
|
|
||||||
const BASE = '/api/v1/slash-commands';
|
const BASE = '/v1/slash-commands';
|
||||||
|
|
||||||
export const slashCommandsClient = {
|
export const slashCommandsClient = {
|
||||||
list(): Promise<SlashCommandDto[]> {
|
async list(): Promise<SlashCommandDto[]> {
|
||||||
return axios.get<SlashCommandDto[]>(BASE).then((r) => r.data);
|
const r = await api.get<SlashCommandDto[]>(BASE);
|
||||||
|
return r.data;
|
||||||
},
|
},
|
||||||
|
|
||||||
get(id: string): Promise<SlashCommandDto> {
|
async get(id: string): Promise<SlashCommandDto> {
|
||||||
return axios.get<SlashCommandDto>(`${BASE}/${id}`).then((r) => r.data);
|
const r = await api.get<SlashCommandDto>(`${BASE}/${id}`);
|
||||||
|
return r.data;
|
||||||
},
|
},
|
||||||
|
|
||||||
create(payload: CreateSlashCommandPayload): Promise<SlashCommandDto> {
|
async create(payload: CreateSlashCommandPayload): Promise<SlashCommandDto> {
|
||||||
return axios.post<SlashCommandDto>(BASE, payload).then((r) => r.data);
|
const r = await api.post<SlashCommandDto>(BASE, payload);
|
||||||
|
return r.data;
|
||||||
},
|
},
|
||||||
|
|
||||||
update(id: string, payload: UpdateSlashCommandPayload): Promise<SlashCommandDto> {
|
async update(id: string, payload: UpdateSlashCommandPayload): Promise<SlashCommandDto> {
|
||||||
return axios
|
const r = await api.patch<SlashCommandDto>(`${BASE}/${id}`, payload);
|
||||||
.patch<SlashCommandDto>(`${BASE}/${id}`, payload)
|
return r.data;
|
||||||
.then((r) => r.data);
|
|
||||||
},
|
},
|
||||||
|
|
||||||
delete(id: string): Promise<void> {
|
async delete(id: string): Promise<void> {
|
||||||
return axios.delete(`${BASE}/${id}`).then(() => undefined);
|
await api.delete(`${BASE}/${id}`);
|
||||||
},
|
},
|
||||||
|
|
||||||
toggle(id: string, isEnabled: boolean): Promise<SlashCommandDto> {
|
async toggle(id: string, isEnabled: boolean): Promise<SlashCommandDto> {
|
||||||
return axios
|
const r = await api.patch<SlashCommandDto>(`${BASE}/${id}`, { isEnabled });
|
||||||
.patch<SlashCommandDto>(`${BASE}/${id}`, { isEnabled })
|
return r.data;
|
||||||
.then((r) => r.data);
|
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
import axios from 'axios';
|
import api from '@/lib/api-client';
|
||||||
|
|
||||||
export interface SyncBlockDto {
|
export interface SyncBlockDto {
|
||||||
id: string;
|
id: string;
|
||||||
|
|
@ -17,26 +17,30 @@ export interface SyncBlockUsageDto {
|
||||||
workspaceId: string;
|
workspaceId: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
const BASE = '/api/v1/sync-blocks';
|
const BASE = '/v1/sync-blocks';
|
||||||
|
|
||||||
export const syncBlocksClient = {
|
export const syncBlocksClient = {
|
||||||
create(content: Record<string, unknown> = {}): Promise<SyncBlockDto> {
|
async create(content: Record<string, unknown> = {}): Promise<SyncBlockDto> {
|
||||||
return axios.post<SyncBlockDto>(BASE, { content }).then((r) => r.data);
|
const r = await api.post<SyncBlockDto>(BASE, { content });
|
||||||
|
return r.data;
|
||||||
},
|
},
|
||||||
|
|
||||||
get(id: string): Promise<SyncBlockDto> {
|
async get(id: string): Promise<SyncBlockDto> {
|
||||||
return axios.get<SyncBlockDto>(`${BASE}/${id}`).then((r) => r.data);
|
const r = await api.get<SyncBlockDto>(`${BASE}/${id}`);
|
||||||
|
return r.data;
|
||||||
},
|
},
|
||||||
|
|
||||||
update(id: string, content: Record<string, unknown>): Promise<SyncBlockDto> {
|
async update(id: string, content: Record<string, unknown>): Promise<SyncBlockDto> {
|
||||||
return axios.patch<SyncBlockDto>(`${BASE}/${id}`, { content }).then((r) => r.data);
|
const r = await api.patch<SyncBlockDto>(`${BASE}/${id}`, { content });
|
||||||
|
return r.data;
|
||||||
},
|
},
|
||||||
|
|
||||||
delete(id: string): Promise<void> {
|
async delete(id: string): Promise<void> {
|
||||||
return axios.delete(`${BASE}/${id}`).then(() => undefined);
|
await api.delete(`${BASE}/${id}`);
|
||||||
},
|
},
|
||||||
|
|
||||||
usages(id: string): Promise<SyncBlockUsageDto[]> {
|
async usages(id: string): Promise<SyncBlockUsageDto[]> {
|
||||||
return axios.get<SyncBlockUsageDto[]>(`${BASE}/${id}/usages`).then((r) => r.data);
|
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 {
|
export interface TemplateDto {
|
||||||
id: string;
|
id: string;
|
||||||
|
|
@ -36,41 +36,46 @@ export interface InstantiatePayload {
|
||||||
name?: string;
|
name?: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
const BASE = '/api/v1/templates';
|
const BASE = '/v1/templates';
|
||||||
|
|
||||||
export const templatesClient = {
|
export const templatesClient = {
|
||||||
list(opts: { category?: string; search?: string } = {}): Promise<TemplateDto[]> {
|
async list(opts: { category?: string; search?: string } = {}): Promise<TemplateDto[]> {
|
||||||
return axios
|
const r = await api.get<TemplateDto[]>(BASE, { params: opts });
|
||||||
.get<TemplateDto[]>(BASE, { params: opts })
|
return r.data;
|
||||||
.then((r) => r.data);
|
|
||||||
},
|
},
|
||||||
|
|
||||||
get(id: string): Promise<TemplateDto> {
|
async get(id: string): Promise<TemplateDto> {
|
||||||
return axios.get<TemplateDto>(`${BASE}/${id}`).then((r) => r.data);
|
const r = await api.get<TemplateDto>(`${BASE}/${id}`);
|
||||||
|
return r.data;
|
||||||
},
|
},
|
||||||
|
|
||||||
create(payload: CreateTemplatePayload): Promise<TemplateDto> {
|
async create(payload: CreateTemplatePayload): Promise<TemplateDto> {
|
||||||
return axios.post<TemplateDto>(BASE, payload).then((r) => r.data);
|
const r = await api.post<TemplateDto>(BASE, payload);
|
||||||
|
return r.data;
|
||||||
},
|
},
|
||||||
|
|
||||||
update(id: string, payload: UpdateTemplatePayload): Promise<TemplateDto> {
|
async update(id: string, payload: UpdateTemplatePayload): Promise<TemplateDto> {
|
||||||
return axios.patch<TemplateDto>(`${BASE}/${id}`, payload).then((r) => r.data);
|
const r = await api.patch<TemplateDto>(`${BASE}/${id}`, payload);
|
||||||
|
return r.data;
|
||||||
},
|
},
|
||||||
|
|
||||||
delete(id: string): Promise<void> {
|
async delete(id: string): Promise<void> {
|
||||||
return axios.delete(`${BASE}/${id}`).then(() => undefined);
|
await api.delete(`${BASE}/${id}`);
|
||||||
},
|
},
|
||||||
|
|
||||||
instantiate(
|
async instantiate(
|
||||||
id: string,
|
id: string,
|
||||||
payload: InstantiatePayload,
|
payload: InstantiatePayload,
|
||||||
): Promise<{ pageId: string; slugId: string }> {
|
): Promise<{ pageId: string; slugId: string }> {
|
||||||
return axios
|
const r = await api.post<{ pageId: string; slugId: string }>(
|
||||||
.post<{ pageId: string; slugId: string }>(`${BASE}/${id}/instantiate`, payload)
|
`${BASE}/${id}/instantiate`,
|
||||||
.then((r) => r.data);
|
payload,
|
||||||
|
);
|
||||||
|
return r.data;
|
||||||
},
|
},
|
||||||
|
|
||||||
setDefault(id: string): Promise<TemplateDto> {
|
async setDefault(id: string): Promise<TemplateDto> {
|
||||||
return axios.patch<TemplateDto>(`${BASE}/${id}/default`).then((r) => r.data);
|
const r = await api.patch<TemplateDto>(`${BASE}/${id}/default`);
|
||||||
|
return r.data;
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue