import Container from 'typedi'; import { ApplicationError, type INode, type IWorkflowCredentials } from 'n8n-workflow'; import { CredentialsRepository } from '@db/repositories/credentials.repository'; // eslint-disable-next-line @typescript-eslint/naming-convention export async function WorkflowCredentials(nodes: INode[]): Promise { // Go through all nodes to find which credentials are needed to execute the workflow const returnCredentials: IWorkflowCredentials = {}; let node; let type; let nodeCredentials; let foundCredentials; for (node of nodes) { if (node.disabled === true || !node.credentials) { continue; } for (type of Object.keys(node.credentials)) { if (!returnCredentials[type]) { returnCredentials[type] = {}; } nodeCredentials = node.credentials[type]; if (!nodeCredentials.id) { throw new ApplicationError( `Credentials with name "${nodeCredentials.name}" for type "${type}" miss an ID.`, { extra: { credentialName: nodeCredentials.name }, tags: { credentialType: type } }, ); } if (!returnCredentials[type][nodeCredentials.id]) { foundCredentials = await Container.get(CredentialsRepository).findOneBy({ id: nodeCredentials.id, type, }); if (!foundCredentials) { throw new ApplicationError('Could not find credential.', { tags: { credentialType: type }, extra: { credentialId: nodeCredentials.id }, }); } returnCredentials[type][nodeCredentials.id] = foundCredentials; } } } return returnCredentials; }