simplify
This commit is contained in:
@@ -1,6 +1,6 @@
|
||||
/**
|
||||
* Queue API Endpoints
|
||||
*
|
||||
*
|
||||
* Provides HTTP interface for queue operations:
|
||||
* - POST /api/queue - Enqueue Instagram URL for processing
|
||||
* - GET /api/queue - List all queue items with optional status filtering
|
||||
@@ -15,135 +15,133 @@ import type { RequestHandler } from './$types';
|
||||
|
||||
/**
|
||||
* POST /api/queue - Enqueue Instagram URL
|
||||
*
|
||||
*
|
||||
* Body: { url: string }
|
||||
* Returns: { id: string, url: string, status: string, enqueuedAt: string }
|
||||
*
|
||||
*
|
||||
* Validates Instagram URL format and enqueues for processing.
|
||||
* Returns 400 for invalid URLs, 500 for server errors.
|
||||
*/
|
||||
export const POST: RequestHandler = async ({ request }) => {
|
||||
try {
|
||||
// Parse JSON body with proper error handling
|
||||
let body;
|
||||
try {
|
||||
body = await request.json();
|
||||
} catch (jsonError) {
|
||||
throw new ValidationError('Invalid JSON in request body');
|
||||
}
|
||||
|
||||
// Validate request body
|
||||
if (!body || typeof body !== 'object') {
|
||||
throw new ValidationError('Request body must be JSON object');
|
||||
}
|
||||
|
||||
const { url } = body;
|
||||
|
||||
// Validate URL presence
|
||||
if (!url || typeof url !== 'string') {
|
||||
throw new ValidationError('URL is required and must be a string');
|
||||
}
|
||||
|
||||
// Validate Instagram URL format using utility
|
||||
const validation = validateInstagramUrl(url);
|
||||
if (!validation.valid) {
|
||||
throw new ValidationError(validation.error || 'Invalid Instagram URL');
|
||||
}
|
||||
|
||||
// Enqueue the URL
|
||||
const queueItem = queueManager.enqueue(url);
|
||||
|
||||
// Return minimal response (full details available at GET /api/queue/{id})
|
||||
return json({
|
||||
id: queueItem.id,
|
||||
url: queueItem.url,
|
||||
status: queueItem.status,
|
||||
enqueuedAt: queueItem.enqueuedAt
|
||||
});
|
||||
|
||||
} catch (error) {
|
||||
return handleApiError(error);
|
||||
}
|
||||
try {
|
||||
// Parse JSON body with proper error handling
|
||||
let body;
|
||||
try {
|
||||
body = await request.json();
|
||||
} catch (jsonError) {
|
||||
throw new ValidationError('Invalid JSON in request body');
|
||||
}
|
||||
|
||||
// Validate request body
|
||||
if (!body || typeof body !== 'object') {
|
||||
throw new ValidationError('Request body must be JSON object');
|
||||
}
|
||||
|
||||
const { url } = body;
|
||||
|
||||
// Validate URL presence
|
||||
if (!url || typeof url !== 'string') {
|
||||
throw new ValidationError('URL is required and must be a string');
|
||||
}
|
||||
|
||||
// Validate Instagram URL format using utility
|
||||
const validation = validateInstagramUrl(url);
|
||||
if (!validation.valid) {
|
||||
throw new ValidationError(validation.error || 'Invalid Instagram URL');
|
||||
}
|
||||
|
||||
// Enqueue the URL
|
||||
const queueItem = queueManager.enqueue(url);
|
||||
|
||||
// Return minimal response (full details available at GET /api/queue/{id})
|
||||
return json({
|
||||
id: queueItem.id,
|
||||
url: queueItem.url,
|
||||
status: queueItem.status,
|
||||
enqueuedAt: queueItem.enqueuedAt
|
||||
});
|
||||
} catch (error) {
|
||||
return handleApiError(error);
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* GET /api/queue - List queue items
|
||||
*
|
||||
*
|
||||
* Query params:
|
||||
* - status?: string - Filter by status (pending, in_progress, success, unhealthy, error)
|
||||
* - limit?: number - Maximum items to return (default: 50, max: 200)
|
||||
* - offset?: number - Pagination offset (default: 0)
|
||||
*
|
||||
*
|
||||
* Returns: { items: QueueItem[], total: number, hasMore: boolean }
|
||||
*/
|
||||
export const GET: RequestHandler = async ({ url }) => {
|
||||
try {
|
||||
const searchParams = url.searchParams;
|
||||
|
||||
// Parse query parameters
|
||||
const statusFilter = searchParams.get('status');
|
||||
const limitParam = searchParams.get('limit');
|
||||
const offsetParam = searchParams.get('offset');
|
||||
|
||||
// Validate and parse limit
|
||||
let limit = 50; // default
|
||||
if (limitParam) {
|
||||
const parsedLimit = parseInt(limitParam, 10);
|
||||
if (isNaN(parsedLimit) || parsedLimit < 1) {
|
||||
throw new ValidationError('Limit must be a positive integer');
|
||||
}
|
||||
if (parsedLimit > 200) {
|
||||
throw new ValidationError('Limit cannot exceed 200');
|
||||
}
|
||||
limit = parsedLimit;
|
||||
}
|
||||
|
||||
// Validate and parse offset
|
||||
let offset = 0; // default
|
||||
if (offsetParam) {
|
||||
const parsedOffset = parseInt(offsetParam, 10);
|
||||
if (isNaN(parsedOffset) || parsedOffset < 0) {
|
||||
throw new ValidationError('Offset must be a non-negative integer');
|
||||
}
|
||||
offset = parsedOffset;
|
||||
}
|
||||
|
||||
// Validate status filter
|
||||
const validStatuses = ['pending', 'in_progress', 'success', 'unhealthy', 'error'];
|
||||
if (statusFilter && !validStatuses.includes(statusFilter)) {
|
||||
throw new ValidationError(
|
||||
`Invalid status filter. Must be one of: ${validStatuses.join(', ')}`
|
||||
);
|
||||
}
|
||||
|
||||
// Get all items
|
||||
let items = queueManager.getAll();
|
||||
const totalCount = items.length;
|
||||
|
||||
// Apply status filter
|
||||
if (statusFilter) {
|
||||
items = items.filter(item => item.status === statusFilter);
|
||||
}
|
||||
|
||||
// Sort by enqueued time (newest first)
|
||||
items.sort((a, b) => new Date(b.enqueuedAt).getTime() - new Date(a.enqueuedAt).getTime());
|
||||
|
||||
// Apply pagination
|
||||
const paginatedItems = items.slice(offset, offset + limit);
|
||||
const hasMore = (offset + limit) < items.length;
|
||||
|
||||
return json({
|
||||
items: paginatedItems,
|
||||
total: statusFilter ? items.length : totalCount,
|
||||
hasMore,
|
||||
pagination: {
|
||||
offset,
|
||||
limit,
|
||||
count: paginatedItems.length
|
||||
}
|
||||
});
|
||||
|
||||
} catch (error) {
|
||||
return handleApiError(error);
|
||||
}
|
||||
};
|
||||
try {
|
||||
const searchParams = url.searchParams;
|
||||
|
||||
// Parse query parameters
|
||||
const statusFilter = searchParams.get('status');
|
||||
const limitParam = searchParams.get('limit');
|
||||
const offsetParam = searchParams.get('offset');
|
||||
|
||||
// Validate and parse limit
|
||||
let limit = 50; // default
|
||||
if (limitParam) {
|
||||
const parsedLimit = parseInt(limitParam, 10);
|
||||
if (isNaN(parsedLimit) || parsedLimit < 1) {
|
||||
throw new ValidationError('Limit must be a positive integer');
|
||||
}
|
||||
if (parsedLimit > 200) {
|
||||
throw new ValidationError('Limit cannot exceed 200');
|
||||
}
|
||||
limit = parsedLimit;
|
||||
}
|
||||
|
||||
// Validate and parse offset
|
||||
let offset = 0; // default
|
||||
if (offsetParam) {
|
||||
const parsedOffset = parseInt(offsetParam, 10);
|
||||
if (isNaN(parsedOffset) || parsedOffset < 0) {
|
||||
throw new ValidationError('Offset must be a non-negative integer');
|
||||
}
|
||||
offset = parsedOffset;
|
||||
}
|
||||
|
||||
// Validate status filter
|
||||
const validStatuses = ['pending', 'in_progress', 'success', 'unhealthy', 'error'];
|
||||
if (statusFilter && !validStatuses.includes(statusFilter)) {
|
||||
throw new ValidationError(
|
||||
`Invalid status filter. Must be one of: ${validStatuses.join(', ')}`
|
||||
);
|
||||
}
|
||||
|
||||
// Get all items
|
||||
let items = queueManager.getAll();
|
||||
const totalCount = items.length;
|
||||
|
||||
// Apply status filter
|
||||
if (statusFilter) {
|
||||
items = items.filter((item) => item.status === statusFilter);
|
||||
}
|
||||
|
||||
// Sort by enqueued time (newest first)
|
||||
items.sort((a, b) => new Date(b.enqueuedAt).getTime() - new Date(a.enqueuedAt).getTime());
|
||||
|
||||
// Apply pagination
|
||||
const paginatedItems = items.slice(offset, offset + limit);
|
||||
const hasMore = offset + limit < items.length;
|
||||
|
||||
return json({
|
||||
items: paginatedItems,
|
||||
total: statusFilter ? items.length : totalCount,
|
||||
hasMore,
|
||||
pagination: {
|
||||
offset,
|
||||
limit,
|
||||
count: paginatedItems.length
|
||||
}
|
||||
});
|
||||
} catch (error) {
|
||||
return handleApiError(error);
|
||||
}
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user