UNPKG

@quintaaa/eslint-plugin-starlims

Version:

Eslint plugin to parse and lint starlims form code successfully

92 lines (89 loc) 3.21 kB
module.exports = { meta: { type: 'problem', docs: { description: 'Detect requests in looops like lims.CallServer() or lims.GetDataSet()', recommended: true, }, }, create(context) { const synchronousRequests = [ 'CallServer', 'GetDataSet', 'GetData', 'GetDataSource', // Technically not sending a request, but does when used with dgd.Data = lims.GetDataSource() (99% of the time) ]; const asyncRequests = [ 'CallServerAsync', 'GetDataSetAsync', 'GetDataAsync', ]; return { CallExpression(node) { if ( node.callee?.object?.name === 'lims' && synchronousRequests .concat(asyncRequests) .includes(node.callee?.property?.name) ) { if (isInLoop(node) || isInArrayLoop(node)) { if ( asyncRequests.includes(node.callee.property.name) && node.parent.type !== 'AwaitExpression' ) return; let message; if (asyncRequests.includes(node.callee.property.name)) message = 'Avoid awaiting requests in loops ({{ function }}). You should either make a server script or datasource that allows you to retrieve the data in one request or do not await each call (Using Promise.all if possible or handling the response in a callback).'; else message = 'Avoid requests in loops ({{ function }}). You should make a server script or datasource that allows you to retrieve the data in one request. Or call the asynchronous version of the function and handle the result afterwards.'; context.report({ node, message, data: { function: node.callee.property.name, }, }); } } }, }; }, }; const isInLoop = (node) => { if ( [ 'ForStatement', 'ForInStatement', 'ForOfStatement', 'WhileStatement', 'DoWhileStatement', ].includes(node.type) ) return true; if (node.parent) return isInLoop(node.parent); return false; }; // Most used array loops const arrayLoops = [ 'forEach', 'map', 'filter', 'reduce', 'reduceRight', 'every', 'some', 'find', ]; const isInArrayLoop = (node) => { if ( node.type === 'CallExpression' && arrayLoops.includes(node.callee?.property?.name) ) return true; if (node.parent) return isInArrayLoop(node.parent); return false; };