@dbs-portal/core-api
Version:
HTTP client and API utilities for DBS Portal
180 lines • 5.89 kB
JavaScript
/**
* MSW handler factory functions
*/
import { http, HttpResponse } from 'msw';
import { getMockConfig } from '../config';
/**
* Create a single MSW handler
*/
export function createHandler(method, path, options) {
const config = getMockConfig();
return http[method.toLowerCase()](path, async ({ request, params }) => {
try {
// Create mock request context
const url = new URL(request.url);
const mockRequest = {
url,
method: request.method,
headers: request.headers,
body: await extractRequestBody(request),
params: params,
query: Object.fromEntries(url.searchParams.entries()),
};
// Simulate delay
const delay = options.delay || config.delay;
if (delay) {
const ms = Array.isArray(delay)
? Math.floor(Math.random() * (delay[1] - delay[0] + 1)) + delay[0]
: delay;
if (ms > 0) {
await new Promise(resolve => setTimeout(resolve, ms));
}
}
// Generate response
const apiResponse = await options.response(mockRequest);
// Create HTTP response
const status = options.status || (apiResponse.success ? 200 : 400);
const headers = {
'Content-Type': 'application/json',
...options.headers,
};
return HttpResponse.json(apiResponse, { status, headers });
}
catch (error) {
console.error(`MSW Handler Error (${method} ${path}):`, error);
// Return error response
return HttpResponse.json({
success: false,
message: 'Mock handler error',
errors: [{ code: 'MOCK_ERROR', message: String(error) }],
}, { status: 500 });
}
});
}
/**
* Create multiple handlers from configuration
*/
export function createHandlers(handlerConfigs) {
return handlerConfigs.map(({ method, path, options }) => createHandler(method, path, options));
}
/**
* Create a GET handler
*/
export function createGetHandler(path, response, options = {}) {
return createHandler('GET', path, { ...options, response });
}
/**
* Create a POST handler
*/
export function createPostHandler(path, response, options = {}) {
return createHandler('POST', path, { ...options, response });
}
/**
* Create a PUT handler
*/
export function createPutHandler(path, response, options = {}) {
return createHandler('PUT', path, { ...options, response });
}
/**
* Create a PATCH handler
*/
export function createPatchHandler(path, response, options = {}) {
return createHandler('PATCH', path, { ...options, response });
}
/**
* Create a DELETE handler
*/
export function createDeleteHandler(path, response, options = {}) {
return createHandler('DELETE', path, { ...options, response });
}
/**
* Create a simple success response handler
*/
export function createSuccessHandler(method, path, data, options = {}) {
const responseFactory = async (request) => {
const responseData = typeof data === 'function' ? await data(request) : data;
return {
success: true,
data: responseData,
message: 'Success',
meta: {
timestamp: new Date().toISOString(),
requestId: generateRequestId(),
version: '1.0.0',
},
};
};
return createHandler(method, path, { ...options, response: responseFactory });
}
/**
* Create an error response handler
*/
export function createErrorHandler(method, path, error, options = {}) {
const responseFactory = async () => {
return {
success: false,
message: error.message,
errors: [{
code: error.code,
message: error.message,
details: error.details,
}],
meta: {
timestamp: new Date().toISOString(),
requestId: generateRequestId(),
version: '1.0.0',
},
};
};
return createHandler(method, path, {
...options,
response: responseFactory,
status: error.status,
});
}
/**
* Create a handler that returns different responses based on conditions
*/
export function createConditionalHandler(method, path, conditions, fallbackResponse, options = {}) {
const responseFactory = async (request) => {
for (const { condition, response } of conditions) {
if (await condition(request)) {
return response(request);
}
}
return fallbackResponse(request);
};
return createHandler(method, path, { ...options, response: responseFactory });
}
/**
* Extract request body safely
*/
async function extractRequestBody(request) {
try {
const contentType = request.headers.get('content-type') || '';
if (contentType.includes('application/json')) {
return await request.json();
}
else if (contentType.includes('application/x-www-form-urlencoded')) {
const formData = await request.formData();
return Object.fromEntries(formData.entries());
}
else if (contentType.includes('multipart/form-data')) {
const formData = await request.formData();
return Object.fromEntries(formData.entries());
}
else {
return await request.text();
}
}
catch {
return null;
}
}
/**
* Generate a unique request ID
*/
function generateRequestId() {
return `req_${Date.now()}_${Math.random().toString(36).substring(2, 11)}`;
}
//# sourceMappingURL=factory.js.map