SurfSense/surfsense_web/lib/apis/documents-api.service.ts

254 lines
7.6 KiB
TypeScript
Raw Normal View History

2025-11-20 11:00:42 +02:00
import {
type CreateDocumentRequest,
createDocumentRequest,
createDocumentResponse,
type DeleteDocumentRequest,
deleteDocumentRequest,
deleteDocumentResponse,
type GetDocumentByChunkRequest,
type GetDocumentRequest,
type GetDocumentsRequest,
type GetDocumentTypeCountsRequest,
getDocumentByChunkRequest,
getDocumentByChunkResponse,
getDocumentRequest,
getDocumentResponse,
getDocumentsRequest,
getDocumentsResponse,
getDocumentTypeCountsRequest,
getDocumentTypeCountsResponse,
type SearchDocumentsRequest,
searchDocumentsRequest,
searchDocumentsResponse,
type UpdateDocumentRequest,
type UploadDocumentRequest,
updateDocumentRequest,
updateDocumentResponse,
uploadDocumentRequest,
uploadDocumentResponse,
} from "@/contracts/types/document.types";
import { ValidationError } from "../error";
import { baseApiService } from "./base-api.service";
class DocumentsApiService {
/**
* Get a list of documents with optional filtering and pagination
*/
getDocuments = async (request: GetDocumentsRequest) => {
const parsedRequest = getDocumentsRequest.safeParse(request);
if (!parsedRequest.success) {
console.error("Invalid request:", parsedRequest.error);
2025-12-20 05:10:47 -08:00
const errorMessage = parsedRequest.error.issues.map((issue) => issue.message).join(", ");
2025-11-20 11:00:42 +02:00
throw new ValidationError(`Invalid request: ${errorMessage}`);
}
// Transform query params to be string values
const transformedQueryParams = parsedRequest.data.queryParams
? Object.fromEntries(
Object.entries(parsedRequest.data.queryParams).map(([k, v]) => {
// Handle array values (document_type)
if (Array.isArray(v)) {
return [k, v.join(",")];
}
return [k, String(v)];
})
)
: undefined;
const queryParams = transformedQueryParams
? new URLSearchParams(transformedQueryParams).toString()
: "";
return baseApiService.get(`/api/v1/documents?${queryParams}`, getDocumentsResponse);
};
/**
* Get a single document by ID
*/
getDocument = async (request: GetDocumentRequest) => {
const parsedRequest = getDocumentRequest.safeParse(request);
if (!parsedRequest.success) {
console.error("Invalid request:", parsedRequest.error);
2025-12-20 05:10:47 -08:00
const errorMessage = parsedRequest.error.issues.map((issue) => issue.message).join(", ");
2025-11-20 11:00:42 +02:00
throw new ValidationError(`Invalid request: ${errorMessage}`);
}
return baseApiService.get(`/api/v1/documents/${request.id}`, getDocumentResponse);
};
/**
* Create documents (extension, crawled URL, or YouTube video)
*/
createDocument = async (request: CreateDocumentRequest) => {
const parsedRequest = createDocumentRequest.safeParse(request);
if (!parsedRequest.success) {
console.error("Invalid request:", parsedRequest.error);
2025-12-20 05:10:47 -08:00
const errorMessage = parsedRequest.error.issues.map((issue) => issue.message).join(", ");
2025-11-20 11:00:42 +02:00
throw new ValidationError(`Invalid request: ${errorMessage}`);
}
return baseApiService.post(`/api/v1/documents`, createDocumentResponse, {
body: parsedRequest.data,
});
};
/**
* Upload document files
*/
uploadDocument = async (request: UploadDocumentRequest) => {
const parsedRequest = uploadDocumentRequest.safeParse(request);
if (!parsedRequest.success) {
console.error("Invalid request:", parsedRequest.error);
2025-12-20 05:10:47 -08:00
const errorMessage = parsedRequest.error.issues.map((issue) => issue.message).join(", ");
2025-11-20 11:00:42 +02:00
throw new ValidationError(`Invalid request: ${errorMessage}`);
}
// Create FormData for file upload
const formData = new FormData();
parsedRequest.data.files.forEach((file) => {
formData.append("files", file);
});
formData.append("search_space_id", String(parsedRequest.data.search_space_id));
return baseApiService.postFormData(`/api/v1/documents/fileupload`, uploadDocumentResponse, {
body: formData,
});
};
/**
* Search documents by title
*/
searchDocuments = async (request: SearchDocumentsRequest) => {
const parsedRequest = searchDocumentsRequest.safeParse(request);
if (!parsedRequest.success) {
console.error("Invalid request:", parsedRequest.error);
2025-12-20 05:10:47 -08:00
const errorMessage = parsedRequest.error.issues.map((issue) => issue.message).join(", ");
2025-11-20 11:00:42 +02:00
throw new ValidationError(`Invalid request: ${errorMessage}`);
}
// Transform query params to be string values
const transformedQueryParams = parsedRequest.data.queryParams
? Object.fromEntries(
Object.entries(parsedRequest.data.queryParams).map(([k, v]) => {
// Handle array values (document_type)
if (Array.isArray(v)) {
return [k, v.join(",")];
}
return [k, String(v)];
})
)
: undefined;
const queryParams = transformedQueryParams
? new URLSearchParams(transformedQueryParams).toString()
: "";
return baseApiService.get(`/api/v1/documents/search?${queryParams}`, searchDocumentsResponse);
};
/**
* Get document type counts
*/
getDocumentTypeCounts = async (request: GetDocumentTypeCountsRequest) => {
// Validate the request
const parsedRequest = getDocumentTypeCountsRequest.safeParse(request);
if (!parsedRequest.success) {
console.error("Invalid request:", parsedRequest.error);
// Format a user friendly error message
2025-12-20 05:10:47 -08:00
const errorMessage = parsedRequest.error.issues.map((issue) => issue.message).join(", ");
2025-11-20 11:00:42 +02:00
throw new ValidationError(`Invalid request: ${errorMessage}`);
}
// Transform query params to be string values
const transformedQueryParams = parsedRequest.data.queryParams
? Object.fromEntries(
Object.entries(parsedRequest.data.queryParams).map(([k, v]) => [k, String(v)])
)
: undefined;
const queryParams = transformedQueryParams
? new URLSearchParams(transformedQueryParams).toString()
: "";
return baseApiService.get(
`/api/v1/documents/type-counts?${queryParams}`,
getDocumentTypeCountsResponse
);
};
/**
* Get document by chunk ID (includes all chunks)
*/
getDocumentByChunk = async (request: GetDocumentByChunkRequest) => {
// Validate the request
const parsedRequest = getDocumentByChunkRequest.safeParse(request);
if (!parsedRequest.success) {
console.error("Invalid request:", parsedRequest.error);
// Format a user friendly error message
2025-12-20 05:10:47 -08:00
const errorMessage = parsedRequest.error.issues.map((issue) => issue.message).join(", ");
2025-11-20 11:00:42 +02:00
throw new ValidationError(`Invalid request: ${errorMessage}`);
}
return baseApiService.get(
`/api/v1/documents/by-chunk/${request.chunk_id}`,
getDocumentByChunkResponse
);
};
/**
* Update a document
*/
updateDocument = async (request: UpdateDocumentRequest) => {
// Validate the request
const parsedRequest = updateDocumentRequest.safeParse(request);
if (!parsedRequest.success) {
console.error("Invalid request:", parsedRequest.error);
// Format a user friendly error message
2025-12-20 05:10:47 -08:00
const errorMessage = parsedRequest.error.issues.map((issue) => issue.message).join(", ");
2025-11-20 11:00:42 +02:00
throw new ValidationError(`Invalid request: ${errorMessage}`);
}
const { id, data } = parsedRequest.data;
return baseApiService.put(`/api/v1/documents/${id}`, updateDocumentResponse, {
body: data,
});
};
/**
* Delete a document
*/
deleteDocument = async (request: DeleteDocumentRequest) => {
// Validate the request
const parsedRequest = deleteDocumentRequest.safeParse(request);
if (!parsedRequest.success) {
console.error("Invalid request:", parsedRequest.error);
// Format a user friendly error message
2025-12-20 05:10:47 -08:00
const errorMessage = parsedRequest.error.issues.map((issue) => issue.message).join(", ");
2025-11-20 11:00:42 +02:00
throw new ValidationError(`Invalid request: ${errorMessage}`);
}
return baseApiService.delete(`/api/v1/documents/${request.id}`, deleteDocumentResponse);
};
}
export const documentsApiService = new DocumentsApiService();