const jsonHeaders = { "Content-Type": "application/json", Accept: "application/json" };
async function request(path, options = {}) {
const response = await fetch(path, {
credentials: "include",
...options,
headers: {
...jsonHeaders,
...(options.headers || {})
}
});
if (response.status === 204) {
return null;
}
const payload = await response.json();
if (!response.ok) {
throw new Error(payload?.error?.message || "Request failed");
}
return payload;
}
export const api = {
health: () => request("/health"),
ready: () => request("/ready"),
me: () => request("/api/v1/me"),
listSecrets: (params = {}) => {
const query = new URLSearchParams(params);
return request(`/api/v1/secrets?${query}`);
},
createSecret: (payload) =>
request("/api/v1/secrets", { method: "POST", body: JSON.stringify(payload) }),
updateSecret: (id, payload) =>
request(`/api/v1/secrets/${id}`, { method: "PATCH", body: JSON.stringify(payload) }),
deleteSecret: (id) => request(`/api/v1/secrets/${id}`, { method: "DELETE" }),
revealSecret: (id) => request(`/api/v1/secrets/${id}/reveal`, { method: "POST" }),
versions: (id) => request(`/api/v1/secrets/${id}/versions`),
revealVersion: (id, versionId) =>
request(`/api/v1/secrets/${id}/versions/${versionId}/reveal`, { method: "POST" }),
audit: () => request("/api/v1/audit-events"),
secretAudit: (id) => request(`/api/v1/secrets/${id}/audit-events`),
tokens: () => request("/api/v1/api-tokens"),
createToken: (payload) =>
request("/api/v1/api-tokens", { method: "POST", body: JSON.stringify(payload) }),
revokeToken: (id) => request(`/api/v1/api-tokens/${id}`, { method: "DELETE" }),
exportData: () => request("/api/v1/export", { method: "POST" }),
importData: (payload) =>
request("/api/v1/import", { method: "POST", body: JSON.stringify(payload) }),
deleteAccountData: () => request("/api/v1/account-data", { method: "DELETE" }),
adminUsers: (params = {}) => {
const query = new URLSearchParams(params);
return request(`/api/v1/admin/users?${query}`);
}
};