airdcpp-apisocket
Version:
Javascript connector for AirDC++ Web API
146 lines • 5.01 kB
JavaScript
const checkAccess = (menuItem, permissions) => {
if (!menuItem.access) {
return true;
}
return permissions.indexOf('admin') !== -1 || permissions.indexOf(menuItem.access) !== -1;
};
const URLS_SUPPORT = 'urls';
const FORM_SUPPORT = 'form';
const hasSupport = (support, supports) => {
return !!supports && supports.indexOf(support) !== -1;
};
// Check whether the item passes the access and filter checks
const validateItem = async (menuItem, data) => {
const { selected_ids, entity_id, permissions, supports } = data;
if (!!menuItem.urls && !hasSupport(URLS_SUPPORT, supports)) {
return false;
}
if (!!menuItem.filter && !(await menuItem.filter({
selectedIds: selected_ids,
entityId: entity_id,
permissions,
supports
}))) {
return false;
}
return checkAccess(menuItem, data.permissions);
};
const parseCallbackData = async (item, data) => {
const { selected_ids, entity_id, permissions, supports } = data;
const callbackProps = {
selectedIds: selected_ids,
entityId: entity_id,
permissions,
supports
};
if (!!item.urls && !!item.urls.length) {
let urls;
if (typeof item.urls === 'function') {
urls = await item.urls(callbackProps);
}
else {
urls = item.urls;
}
return {
urls,
};
}
else if (!!item.formDefinitions && hasSupport(FORM_SUPPORT, supports)) {
let formDefinitions;
if (typeof item.formDefinitions === 'function') {
formDefinitions = await item.formDefinitions(callbackProps);
}
else {
formDefinitions = item.formDefinitions;
}
return {
form_definitions: formDefinitions,
};
}
return {};
};
const findMenuItemById = (id, menuItems) => {
for (const item of menuItems) {
if (item.id === id) {
return item;
}
if (item.children) {
const found = findMenuItemById(id, item.children);
if (found) {
return found;
}
}
}
return undefined;
};
export const addContextMenuItems = async (socket, menuItems, menuTypeId, menu) => {
const removeListener = await socket.addListener('menus', `${menuTypeId}_menuitem_selected`, async (data) => {
if (data.hook_id === menu.id) {
const menuItem = findMenuItemById(data.menuitem_id, menuItems);
if (!!menuItem) {
const isValid = await validateItem(menuItem, data);
if (isValid && !!menuItem.onClick) {
const { selected_ids, entity_id, permissions, supports, form_values } = data;
menuItem.onClick({
selectedIds: selected_ids,
entityId: entity_id,
permissions,
supports,
formValues: form_values
});
}
}
}
});
const parseMenuItem = async (item, data) => {
const isValid = await validateItem(item, data);
if (isValid) {
const parsedCallbackData = await parseCallbackData(item, data);
const { onClick, id, title, icon, children } = item;
const isValid = !!onClick || (!!parsedCallbackData.urls && parsedCallbackData.urls.length) || !!children;
if (isValid) {
const validChildren = [];
if (children) {
for (const child of children) {
const validChild = await parseMenuItem(child, data);
if (validChild) {
validChildren.push(validChild);
}
}
}
const validItem = {
id,
title,
icon,
...parsedCallbackData,
};
if (validChildren.length > 0) {
validItem.children = validChildren;
}
return validItem;
}
else {
socket.logger.warn(`Context menu item ${id} does not have a valid action, children or URLs, skipping`, item);
}
}
return null;
};
const removeHook = await socket.addHook('menus', `${menuTypeId}_list_menuitems`, async (data, accept, reject) => {
const validItems = [];
for (const item of menuItems) {
const validItem = await parseMenuItem(item, data);
if (validItem) {
validItems.push(validItem);
}
}
accept({
menuitems: validItems,
icon: menu.icon,
});
}, menu);
return async () => {
await removeHook();
await removeListener();
};
};
//# sourceMappingURL=PublicHelpers.js.map