@dbs-portal/core-api
Version:
HTTP client and API utilities for DBS Portal
298 lines • 10.7 kB
JavaScript
/**
* CRUD operation mock handlers
*/
import { createHandler as createMockHandler } from './factory';
import { generateId } from '../utils/data-generator';
/**
* In-memory data store for CRUD operations
*/
class MockDataStore {
data = new Map();
constructor(initialData = []) {
initialData.forEach(item => {
this.data.set(item.id, item);
});
}
getAll() {
return Array.from(this.data.values());
}
getById(id) {
return this.data.get(id);
}
create(item) {
const id = generateId();
const newItem = { ...item, id };
this.data.set(id, newItem);
return newItem;
}
update(id, updates) {
const existing = this.data.get(id);
if (!existing)
return null;
const updated = { ...existing, ...updates, id };
this.data.set(id, updated);
return updated;
}
delete(id) {
return this.data.delete(id);
}
clear() {
this.data.clear();
}
count() {
return this.data.size;
}
search(predicate) {
return this.getAll().filter(predicate);
}
paginate(page, pageSize, filter) {
const allItems = filter ? this.getAll().filter(filter) : this.getAll();
const total = allItems.length;
const totalPages = Math.ceil(total / pageSize);
const startIndex = (page - 1) * pageSize;
const endIndex = startIndex + pageSize;
const items = allItems.slice(startIndex, endIndex);
return {
items,
total,
totalPages,
currentPage: page,
hasNext: page < totalPages,
hasPrevious: page > 1,
};
}
}
/**
* Create CRUD handlers for a resource
*/
export function createCrudHandlers(options) {
const store = new MockDataStore(options.initialData || []);
const { basePath, dataFactory, pagination, validate } = options;
// GET /resource - List with pagination
const listHandler = createMockHandler('GET', `${basePath}`, {
response: async (request) => {
const page = Number.parseInt(request.query['page'] || '1', 10);
const pageSize = Math.min(Number.parseInt(request.query['pageSize'] || String(pagination?.defaultPageSize || 10), 10), pagination?.maxPageSize || 100);
const search = request.query['search'] || request.query['filter'] || '';
// Apply search filter if provided
const filterFn = search
? (item) => JSON.stringify(item).toLowerCase().includes(search.toLowerCase())
: undefined;
const result = store.paginate(page, pageSize, filterFn);
const paginatedResponse = {
data: result.items,
meta: {
total: result.total,
page,
limit: pageSize,
totalPages: result.totalPages,
hasNext: result.hasNext,
hasPrevious: result.hasPrevious,
}
};
return {
success: true,
data: paginatedResponse,
message: 'Items retrieved successfully',
meta: {
timestamp: new Date().toISOString(),
requestId: generateId(),
version: '1.0.0',
},
};
},
});
// GET /resource/:id - Get by ID
const getByIdHandler = createMockHandler('GET', `${basePath}/:id`, {
response: async (request) => {
const id = request.params['id'];
if (!id) {
return {
success: false,
message: 'ID parameter is required',
errors: [{ code: 'MISSING_ID', message: 'ID parameter is required' }],
meta: {
timestamp: new Date().toISOString(),
requestId: generateId(),
version: '1.0.0',
},
};
}
const item = store.getById(id);
if (!item) {
return {
success: false,
message: 'Item not found',
errors: [{ code: 'NOT_FOUND', message: `Item with id ${id} not found` }],
meta: {
timestamp: new Date().toISOString(),
requestId: generateId(),
version: '1.0.0',
},
};
}
return {
success: true,
data: item,
message: 'Item retrieved successfully',
meta: {
timestamp: new Date().toISOString(),
requestId: generateId(),
version: '1.0.0',
},
};
},
});
// POST /resource - Create
const createHandlerInstance = createMockHandler('POST', `${basePath}`, {
response: async (request) => {
const data = request.body;
// Validate if validator is provided
if (validate) {
const errors = validate(data);
if (errors && errors.length > 0) {
return {
success: false,
message: 'Validation failed',
errors: errors.map(error => ({ code: 'VALIDATION_ERROR', message: error })),
meta: {
timestamp: new Date().toISOString(),
requestId: generateId(),
version: '1.0.0',
},
};
}
}
// Create item using factory if data is incomplete
const itemData = dataFactory ? { ...dataFactory(data), ...data } : data;
const newItem = store.create(itemData);
return {
success: true,
data: newItem,
message: 'Item created successfully',
meta: {
timestamp: new Date().toISOString(),
requestId: generateId(),
version: '1.0.0',
},
};
},
status: 201,
});
// PUT /resource/:id - Update
const updateHandler = createMockHandler('PUT', `${basePath}/:id`, {
response: async (request) => {
const id = request.params['id'];
if (!id) {
return {
success: false,
message: 'ID parameter is required',
errors: [{ code: 'MISSING_ID', message: 'ID parameter is required' }],
meta: {
timestamp: new Date().toISOString(),
requestId: generateId(),
version: '1.0.0',
},
};
}
const data = request.body;
// Validate if validator is provided
if (validate) {
const errors = validate(data);
if (errors && errors.length > 0) {
return {
success: false,
message: 'Validation failed',
errors: errors.map(error => ({ code: 'VALIDATION_ERROR', message: error })),
meta: {
timestamp: new Date().toISOString(),
requestId: generateId(),
version: '1.0.0',
},
};
}
}
const updatedItem = store.update(id, data);
if (!updatedItem) {
return {
success: false,
message: 'Item not found',
errors: [{ code: 'NOT_FOUND', message: `Item with id ${id} not found` }],
meta: {
timestamp: new Date().toISOString(),
requestId: generateId(),
version: '1.0.0',
},
};
}
return {
success: true,
data: updatedItem,
message: 'Item updated successfully',
meta: {
timestamp: new Date().toISOString(),
requestId: generateId(),
version: '1.0.0',
},
};
},
});
// DELETE /resource/:id - Delete
const deleteHandler = createMockHandler('DELETE', `${basePath}/:id`, {
response: async (request) => {
const id = request.params['id'];
if (!id) {
return {
success: false,
message: 'ID parameter is required',
errors: [{ code: 'MISSING_ID', message: 'ID parameter is required' }],
meta: {
timestamp: new Date().toISOString(),
requestId: generateId(),
version: '1.0.0',
},
};
}
const deleted = store.delete(id);
if (!deleted) {
return {
success: false,
message: 'Item not found',
errors: [{ code: 'NOT_FOUND', message: `Item with id ${id} not found` }],
meta: {
timestamp: new Date().toISOString(),
requestId: generateId(),
version: '1.0.0',
},
};
}
return {
success: true,
data: null,
message: 'Item deleted successfully',
meta: {
timestamp: new Date().toISOString(),
requestId: generateId(),
version: '1.0.0',
},
};
},
status: 204,
});
return [listHandler, getByIdHandler, createHandlerInstance, updateHandler, deleteHandler];
}
/**
* Create simple CRUD handlers with minimal configuration
*/
export function createSimpleCrudHandlers(basePath, dataFactory, initialData = []) {
return createCrudHandlers({
basePath,
dataFactory,
initialData,
pagination: {
defaultPageSize: 10,
maxPageSize: 100,
},
});
}
//# sourceMappingURL=crud-handlers.js.map