mcpengine/servers/toast/dist/api-client.js

201 lines
9.9 KiB
JavaScript

import axios from 'axios';
export class ToastAPIError extends Error {
statusCode;
response;
constructor(message, statusCode, response) {
super(message);
this.statusCode = statusCode;
this.response = response;
this.name = 'ToastAPIError';
}
}
export class ToastAPIClient {
client;
config;
constructor(config) {
this.config = {
baseUrl: config.baseUrl || 'https://ws-api.toasttab.com',
...config,
};
this.client = axios.create({
baseURL: this.config.baseUrl,
headers: {
'Authorization': `Bearer ${this.config.apiToken}`,
'Content-Type': 'application/json',
'Toast-Restaurant-External-ID': this.config.restaurantGuid,
},
timeout: 30000,
});
// Response interceptor for error handling
this.client.interceptors.response.use((response) => response, (error) => {
if (error.response) {
const errorData = error.response.data;
throw new ToastAPIError(errorData?.message || error.message, error.response.status, error.response.data);
}
else if (error.request) {
throw new ToastAPIError('No response received from Toast API');
}
else {
throw new ToastAPIError(error.message);
}
});
}
// Generic GET request with pagination support
async get(endpoint, params, config) {
const response = await this.client.get(endpoint, {
params,
...config,
});
return response.data;
}
// Generic POST request
async post(endpoint, data, config) {
const response = await this.client.post(endpoint, data, config);
return response.data;
}
// Generic PUT request
async put(endpoint, data, config) {
const response = await this.client.put(endpoint, data, config);
return response.data;
}
// Generic PATCH request
async patch(endpoint, data, config) {
const response = await this.client.patch(endpoint, data, config);
return response.data;
}
// Generic DELETE request
async delete(endpoint, config) {
const response = await this.client.delete(endpoint, config);
return response.data;
}
// Paginated GET request
async getPaginated(endpoint, pagination, additionalParams) {
const params = {
page: pagination?.page || 1,
pageSize: pagination?.pageSize || 100,
...additionalParams,
};
const response = await this.get(endpoint, params);
// If the API returns pagination metadata, use it
// Otherwise, create a simple paginated response
return {
data: Array.isArray(response) ? response : [],
page: params.page,
pageSize: params.pageSize,
totalPages: 1,
totalCount: Array.isArray(response) ? response.length : 0,
};
}
// Get all pages automatically
async getAllPages(endpoint, pageSize = 100, additionalParams) {
const allData = [];
let page = 1;
let hasMore = true;
while (hasMore) {
const response = await this.getPaginated(endpoint, { page, pageSize }, additionalParams);
allData.push(...response.data);
// Check if there are more pages
hasMore = response.data.length === pageSize && page < response.totalPages;
page++;
}
return allData;
}
// Orders API
orders = {
list: (params) => this.getPaginated('/orders/v2/orders', params?.pagination, {
startDate: params?.startDate,
endDate: params?.endDate,
}),
get: (orderId) => this.get(`/orders/v2/orders/${orderId}`),
create: (orderData) => this.post('/orders/v2/orders', orderData),
update: (orderId, orderData) => this.put(`/orders/v2/orders/${orderId}`, orderData),
void: (orderId, voidReason) => this.post(`/orders/v2/orders/${orderId}/void`, { voidReason }),
listChecks: (orderId) => this.get(`/orders/v2/orders/${orderId}/checks`),
addItem: (orderId, checkId, itemData) => this.post(`/orders/v2/orders/${orderId}/checks/${checkId}/selections`, itemData),
removeItem: (orderId, checkId, selectionId) => this.delete(`/orders/v2/orders/${orderId}/checks/${checkId}/selections/${selectionId}`),
applyDiscount: (orderId, checkId, discountData) => this.post(`/orders/v2/orders/${orderId}/checks/${checkId}/appliedDiscounts`, discountData),
};
// Menus API
menus = {
list: () => this.get('/menus/v2/menus'),
get: (menuId) => this.get(`/menus/v2/menus/${menuId}`),
listGroups: (menuId) => this.get(`/menus/v2/menus/${menuId}/groups`),
getGroup: (menuId, groupId) => this.get(`/menus/v2/menus/${menuId}/groups/${groupId}`),
listItems: (menuId, groupId) => groupId
? this.get(`/menus/v2/menus/${menuId}/groups/${groupId}/items`)
: this.get(`/menus/v2/menus/${menuId}/items`),
getItem: (menuId, itemId) => this.get(`/menus/v2/menus/${menuId}/items/${itemId}`),
listModifiers: (menuId, itemId) => this.get(`/menus/v2/menus/${menuId}/items/${itemId}/modifierGroups`),
updatePrice: (menuId, itemId, price) => this.patch(`/menus/v2/menus/${menuId}/items/${itemId}`, { price }),
};
// Employees API
employees = {
list: (pagination) => this.getPaginated('/labor/v1/employees', pagination),
get: (employeeId) => this.get(`/labor/v1/employees/${employeeId}`),
create: (employeeData) => this.post('/labor/v1/employees', employeeData),
update: (employeeId, employeeData) => this.put(`/labor/v1/employees/${employeeId}`, employeeData),
delete: (employeeId) => this.delete(`/labor/v1/employees/${employeeId}`),
listJobs: (employeeId) => this.get(`/labor/v1/employees/${employeeId}/jobs`),
listShifts: (employeeId, startDate, endDate) => this.get(`/labor/v1/employees/${employeeId}/shifts`, { startDate, endDate }),
clockIn: (employeeId, jobId) => this.post(`/labor/v1/employees/${employeeId}/timeEntries`, {
jobGuid: jobId,
inDate: new Date().toISOString(),
}),
clockOut: (employeeId, timeEntryId) => this.patch(`/labor/v1/employees/${employeeId}/timeEntries/${timeEntryId}`, {
outDate: new Date().toISOString(),
}),
listTimeEntries: (employeeId, startDate, endDate) => this.get(`/labor/v1/employees/${employeeId}/timeEntries`, { startDate, endDate }),
};
// Labor API
labor = {
listShifts: (startDate, endDate, pagination) => this.getPaginated('/labor/v1/shifts', pagination, { startDate, endDate }),
getShift: (shiftId) => this.get(`/labor/v1/shifts/${shiftId}`),
listBreaks: (shiftId) => this.get(`/labor/v1/shifts/${shiftId}/breaks`),
getLaborCost: (businessDate) => this.get('/labor/v1/laborCost', { businessDate }),
listJobs: () => this.get('/labor/v1/jobs'),
};
// Restaurant API
restaurant = {
getInfo: () => this.get('/restaurants/v1/restaurants/' + this.config.restaurantGuid),
listRevenueCenters: () => this.get('/restaurants/v1/restaurants/' + this.config.restaurantGuid + '/revenueCenters'),
listDiningOptions: () => this.get('/restaurants/v1/restaurants/' + this.config.restaurantGuid + '/diningOptions'),
listServiceAreas: () => this.get('/restaurants/v1/restaurants/' + this.config.restaurantGuid + '/serviceAreas'),
listTables: (serviceAreaId) => serviceAreaId
? this.get(`/restaurants/v1/restaurants/${this.config.restaurantGuid}/serviceAreas/${serviceAreaId}/tables`)
: this.get(`/restaurants/v1/restaurants/${this.config.restaurantGuid}/tables`),
};
// Payments API
payments = {
list: (startDate, endDate, pagination) => this.getPaginated('/payments/v1/payments', pagination, { startDate, endDate }),
get: (paymentId) => this.get(`/payments/v1/payments/${paymentId}`),
void: (paymentId, voidReason) => this.post(`/payments/v1/payments/${paymentId}/void`, { voidReason }),
refund: (paymentId, refundAmount, refundReason) => this.post(`/payments/v1/payments/${paymentId}/refund`, {
refundAmount,
refundReason,
}),
listTips: (startDate, endDate) => this.get('/payments/v1/tips', { startDate, endDate }),
};
// Inventory API (Note: Toast may not have full inventory API, these are examples)
inventory = {
listItems: (pagination) => this.getPaginated('/inventory/v1/items', pagination),
getItem: (itemId) => this.get(`/inventory/v1/items/${itemId}`),
updateCount: (itemId, quantity) => this.patch(`/inventory/v1/items/${itemId}`, { currentQuantity: quantity }),
listVendors: () => this.get('/inventory/v1/vendors'),
createPurchaseOrder: (poData) => this.post('/inventory/v1/purchaseOrders', poData),
};
// Customers API (Note: Toast may not have full customer API, these are examples)
customers = {
list: (pagination) => this.getPaginated('/customers/v1/customers', pagination),
get: (customerId) => this.get(`/customers/v1/customers/${customerId}`),
create: (customerData) => this.post('/customers/v1/customers', customerData),
update: (customerId, customerData) => this.put(`/customers/v1/customers/${customerId}`, customerData),
listLoyalty: (customerId) => this.get(`/customers/v1/customers/${customerId}/loyalty`),
addLoyaltyPoints: (customerId, points) => this.post(`/customers/v1/customers/${customerId}/loyalty/points`, { points }),
};
// Cash Management API
cash = {
listEntries: (startDate, endDate, pagination) => this.getPaginated('/cash/v1/entries', pagination, { startDate, endDate }),
getDrawerStatus: (drawerId) => this.get(`/cash/v1/drawers/${drawerId}`),
};
}
//# sourceMappingURL=api-client.js.map