196 lines
5.3 KiB
TypeScript
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 };
|
|
}
|
|
} |