Files
leaudit-platform-frontend/app/api/postgrest-client.ts
T

196 lines
5.3 KiB
TypeScript

// app/api/postgrest-client.ts
import { apiRequest, type QueryParams } from './client';
import { handleApiError } from './error-handler';
/**
* PostgresREST 特定的查询参数接口
*/
export interface PostgrestParams {
select?: string;
order?: string;
limit?: number;
offset?: number;
filter?: Record<string, unknown>;
schema?: string; // 指定 PostgreSQL schema
[key: string]: unknown; // 允许添加其他参数
}
/**
* 将通用查询参数转换为 PostgresREST 支持的格式
* @param params 查询参数
* @returns 转换后的 PostgresREST 参数
*/
export function transformParams(params: PostgrestParams): QueryParams {
const result: QueryParams = {};
// 处理 select 参数
if (params.select) {
result.select = params.select;
}
// 处理 order 参数
if (params.order) {
result.order = params.order;
}
// 处理 limit 和 offset 参数
if (params.limit !== undefined) {
result.limit = params.limit;
}
if (params.offset !== undefined) {
result.offset = params.offset;
}
// 处理 schema 参数
if (params.schema) {
result.schema = params.schema;
}
// 处理过滤条件 - PostgresREST 格式
if (params.filter) {
Object.entries(params.filter).forEach(([key, value]) => {
// 如果值不为 undefined,则添加到查询参数中
if (value !== undefined) {
// 支持 PostgreSQL 的比较操作符 (eq, gt, lt, gte, lte, like, ilike 等)
result[key] = value as string | number | boolean;
}
});
}
// 处理其他额外参数
Object.entries(params).forEach(([key, value]) => {
// 跳过已处理的特殊参数
if (!['select', 'order', 'limit', 'offset', 'filter', 'schema'].includes(key) && value !== undefined) {
result[key] = value as string | number | boolean;
}
});
return result;
}
/**
* 发送 GET 请求到 PostgresREST 接口
* @param endpoint 端点
* @param params 查询参数
* @returns 响应数据
*/
export async function postgrestGet<T>(endpoint: string, params?: PostgrestParams): Promise<{data: T; error?: never} | {data?: never; error: string; status?: number}> {
try {
const queryParams = params ? transformParams(params) : {};
// 添加前缀表示使用 docauditai 数据库
const apiEndpoint = endpoint.startsWith('/') ? endpoint : `/${endpoint}`;
const response = await apiRequest<T>(
apiEndpoint,
{ method: 'GET' },
queryParams
);
if (response.error) {
throw new Error(response.error);
}
return { data: response.data as T };
} catch (error) {
const apiError = handleApiError(error);
return { error: apiError.message, status: apiError.status };
}
}
/**
* 发送 POST 请求到 PostgresREST 接口
* @param endpoint 端点
* @param data 请求体数据
* @returns 响应数据
*/
export async function postgrestPost<T, D = Record<string, unknown>>(endpoint: string, data: D): Promise<{data: T; error?: never} | {data?: never; error: string; status?: number}> {
try {
// 添加前缀表示使用 docauditai 数据库
const apiEndpoint = endpoint.startsWith('/') ? endpoint : `/${endpoint}`;
const response = await apiRequest<T>(
apiEndpoint,
{
method: 'POST',
body: JSON.stringify(data),
headers: {
'Prefer': 'return=representation'
}
}
);
if (response.error) {
throw new Error(response.error);
}
return { data: response.data as T };
} catch (error) {
const apiError = handleApiError(error);
return { error: apiError.message, status: apiError.status };
}
}
/**
* 发送 PUT 请求到 PostgresREST 接口
* @param endpoint 端点
* @param data 请求体数据
* @returns 响应数据
*/
export async function postgrestPut<T, D = Record<string, unknown>>(endpoint: string, data: D): Promise<{data: T; error?: never} | {data?: never; error: string; status?: number}> {
try {
// 添加前缀表示使用 docauditai 数据库
const apiEndpoint = endpoint.startsWith('/') ? endpoint : `/${endpoint}`;
const response = await apiRequest<T>(
apiEndpoint,
{
method: 'PUT',
body: JSON.stringify(data),
headers: {
'Prefer': 'return=representation'
}
}
);
if (response.error) {
throw new Error(response.error);
}
return { data: response.data as T };
} catch (error) {
const apiError = handleApiError(error);
return { error: apiError.message, status: apiError.status };
}
}
/**
* 发送 DELETE 请求到 PostgresREST 接口
* @param endpoint 端点
* @returns 响应数据
*/
export async function postgrestDelete<T>(endpoint: string): Promise<{data: T; error?: never} | {data?: never; error: string; status?: number}> {
try {
// 添加前缀表示使用 docauditai 数据库
const apiEndpoint = endpoint.startsWith('/') ? endpoint : `/${endpoint}`;
const response = await apiRequest<T>(
apiEndpoint,
{
method: 'DELETE',
headers: {
'Prefer': 'return=representation'
}
}
);
if (response.error) {
throw new Error(response.error);
}
return { data: response.data as T };
} catch (error) {
const apiError = handleApiError(error);
return { error: apiError.message, status: apiError.status };
}
}