UNPKG

@traien/n8n-nodes-espocrm

Version:
536 lines 24.6 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.EspoCRM = void 0; const n8n_workflow_1 = require("n8n-workflow"); const account_operations_1 = require("./operations/account/account.operations"); const contact_operations_1 = require("./operations/contact/contact.operations"); const lead_operations_1 = require("./operations/lead/lead.operations"); const dynamic_operations_1 = require("./operations/dynamic/dynamic.operations"); const meeting_operations_1 = require("./operations/meeting/meeting.operations"); const task_operations_1 = require("./operations/task/task.operations"); const call_operations_1 = require("./operations/call/call.operations"); const opportunity_operations_1 = require("./operations/opportunity/opportunity.operations"); const attachment_operations_1 = require("./operations/attachment/attachment.operations"); const document_operations_1 = require("./operations/document/document.operations"); const case_operations_1 = require("./operations/case/case.operations"); const HandlerFactory_1 = require("./handlers/HandlerFactory"); const MetadataService_1 = require("./services/MetadataService"); const GenericFunctions_1 = require("./GenericFunctions"); class EspoCRM { constructor() { this.description = { displayName: 'EspoCRM', name: 'espoCrm', icon: 'file:espocrm.svg', group: ['transform'], version: 1, subtitle: '={{$parameter["operation"] + ": " + $parameter["resource"]}}', description: 'Interact with EspoCRM API', defaults: { name: 'EspoCRM', }, inputs: ['main'], outputs: ['main'], credentials: [ { name: 'espoCRMApi', required: true, }, ], documentationUrl: 'https://docs.espocrm.com/development/api/', properties: [ { displayName: 'Resource', name: 'resource', type: 'options', noDataExpression: true, options: [ { name: 'Account', value: 'account', }, { name: 'Contact', value: 'contact', }, { name: 'Custom Entity', value: 'customEntity', }, { name: 'Dynamic', value: 'dynamic', }, { name: 'Lead', value: 'lead', }, { name: 'Meeting', value: 'meeting', }, { name: 'Task', value: 'task', }, { name: 'Call', value: 'call', }, { name: 'Opportunity', value: 'opportunity', }, { name: 'Case', value: 'case', }, { name: 'Attachment', value: 'attachment', }, { name: 'Document', value: 'document', }, ], default: 'contact', }, { displayName: 'Entity Type Name or ID', name: 'entityType', type: 'options', typeOptions: { loadOptionsMethod: 'getEntityTypes', }, default: '', required: true, displayOptions: { show: { resource: ['customEntity'], }, }, description: 'Type of entity to interact with (e.g., Opportunity, Case, Product). Choose from the list, or specify an ID using an <a href="https://docs.n8n.io/code-examples/expressions/">expression</a>.', }, ...account_operations_1.accountOperations, ...account_operations_1.accountFields, ...contact_operations_1.contactOperations, ...contact_operations_1.contactFields, ...lead_operations_1.leadOperations, ...lead_operations_1.leadFields, ...meeting_operations_1.meetingOperations, ...meeting_operations_1.meetingFields, ...task_operations_1.taskOperations, ...task_operations_1.taskFields, ...call_operations_1.callOperations, ...call_operations_1.callFields, ...opportunity_operations_1.opportunityOperations, ...opportunity_operations_1.opportunityFields, ...case_operations_1.caseOperations, ...case_operations_1.caseFields, ...attachment_operations_1.attachmentOperations, ...attachment_operations_1.attachmentFields, ...document_operations_1.documentOperations, ...document_operations_1.documentFields, ...dynamic_operations_1.dynamicOperations, ...dynamic_operations_1.dynamicFields, { displayName: 'Operation', name: 'operation', type: 'options', noDataExpression: true, displayOptions: { show: { resource: ['customEntity'], }, }, options: [ { name: 'Create', value: 'create', description: 'Create a new record', action: 'Create a record', }, { name: 'Delete', value: 'delete', description: 'Delete a record', action: 'Delete a record', }, { name: 'Get', value: 'get', description: 'Get a single record', action: 'Get a record', }, { name: 'Get Many', value: 'getAll', description: 'Get many records', action: 'Get many records', }, { name: 'Update', value: 'update', description: 'Update a record', action: 'Update a record', }, ], default: 'create', }, { displayName: 'Data', name: 'data', type: 'json', default: '', required: true, displayOptions: { show: { resource: ['customEntity'], operation: ['create'], }, }, description: 'Data of the record to create', }, { displayName: 'Record ID', name: 'id', type: 'string', default: '', required: true, displayOptions: { show: { resource: ['customEntity'], operation: ['get', 'update', 'delete'], }, }, description: 'ID of the record', }, { displayName: 'Data', name: 'data', type: 'json', default: '', required: true, displayOptions: { show: { resource: ['customEntity'], operation: ['update'], }, }, description: 'Data to update the record with', }, { displayName: 'Return All', name: 'returnAll', type: 'boolean', displayOptions: { show: { resource: ['customEntity'], operation: ['getAll'], }, }, default: false, description: 'Whether to return all results or only up to a given limit', }, { displayName: 'Limit', name: 'limit', type: 'number', displayOptions: { show: { resource: ['customEntity'], operation: ['getAll'], returnAll: [false], }, }, typeOptions: { minValue: 1, }, default: 50, description: 'Max number of results to return', }, { displayName: 'Filter Options', name: 'filterOptions', type: 'collection', placeholder: 'Add Filter Option', default: {}, displayOptions: { show: { resource: ['customEntity'], operation: ['getAll'], }, }, options: [ { displayName: 'Boolean Filter List', name: 'boolFilterList', type: 'string', default: '', placeholder: 'onlyMy,followed', description: 'Comma-separated list of predefined boolean filters', }, { displayName: 'Offset', name: 'offset', type: 'number', default: 0, description: 'Number of results to skip (for pagination)', }, { displayName: 'Order By', name: 'orderBy', type: 'string', default: '', placeholder: 'createdAt', description: 'Field to sort results by', }, { displayName: 'Order Direction', name: 'order', type: 'options', options: [ { name: 'Ascending', value: 'asc', }, { name: 'Descending', value: 'desc', }, ], default: 'asc', description: 'Direction to sort results by', }, { displayName: 'Primary Filter', name: 'primaryFilter', type: 'string', default: '', description: 'Context-specific base filter to apply', }, { displayName: 'Select Fields', name: 'select', type: 'string', default: '', placeholder: 'id,name', description: 'Comma-separated list of fields to return', }, { displayName: 'Where (Filter Conditions)', name: 'where', type: 'json', default: '[]', typeOptions: { alwaysParseJson: true, }, description: 'Filter conditions for the query as defined in the EspoCRM API', }, { displayName: 'Skip Total Count', name: 'skipTotalCount', type: 'boolean', default: false, description: 'Whether to skip calculating total count for large datasets to improve performance', }, ], }, ], }; this.methods = { loadOptions: { async getEntityTypes() { try { const entityTypes = await MetadataService_1.MetadataService.getEntityList.call(this, this); return entityTypes.map(entityType => ({ name: entityType, value: entityType, })).sort((a, b) => a.name.localeCompare(b.name)); } catch (error) { console.error('Error loading entity types:', error); return [{ name: 'Error Loading Entity Types', value: '' }]; } }, async getEntityFields() { const entityType = this.getCurrentNodeParameter('entityType'); if (!entityType) { return [{ name: 'Please Select an Entity Type First', value: '' }]; } try { const fieldDefs = await MetadataService_1.MetadataService.getFieldDefs.call(this, this, entityType); return Object.keys(fieldDefs).map(fieldName => { const fieldDef = fieldDefs[fieldName]; const label = fieldDef.label ? `${fieldDef.label} (${fieldName})` : fieldName; return { name: label, value: fieldName, }; }).sort((a, b) => a.name.localeCompare(b.name)); } catch (error) { console.error(`Error loading fields for entity type ${entityType}:`, error); return [{ name: `Error loading fields for ${entityType}`, value: '' }]; } }, async getEnumOptions() { const entityType = this.getCurrentNodeParameter('entityType'); const fieldName = this.getCurrentNodeParameter('field'); if (!entityType || !fieldName) { return [{ name: 'Please Select an Entity Type and Field First', value: '' }]; } try { const fieldDefs = await MetadataService_1.MetadataService.getFieldDefs.call(this, this, entityType); const fieldDef = fieldDefs[fieldName]; if (fieldDef && fieldDef.type === 'enum' && fieldDef.options) { const options = fieldDef.options; return options.map((option) => ({ name: option, value: option, })); } return [{ name: 'Not an Enum Field or No Options Available', value: '' }]; } catch (error) { console.error(`Error loading enum options for ${entityType}.${fieldName}:`, error); return [{ name: `Error loading options for ${fieldName}`, value: '' }]; } }, }, }; } async execute() { const items = this.getInputData(); const returnData = []; for (let i = 0; i < items.length; i++) { try { const resource = this.getNodeParameter('resource', i); const operation = this.getNodeParameter('operation', i); if (resource === 'dynamic') { const operation = this.getNodeParameter('operation', i); const entityType = this.getNodeParameter('entityType', i); if (operation === 'create') { const dataToSend = {}; const fields = this.getNodeParameter('fieldsUi.fieldValues', i, []); for (const field of fields) { dataToSend[field.fieldName] = field.fieldValue; } const endpoint = `/${entityType}`; const responseData = await GenericFunctions_1.espoApiRequest.call(this, 'POST', endpoint, dataToSend); returnData.push(responseData); } else if (operation === 'get') { const recordId = this.getNodeParameter('recordId', i); const endpoint = `/${entityType}/${recordId}`; const responseData = await GenericFunctions_1.espoApiRequest.call(this, 'GET', endpoint, {}); returnData.push(responseData); } else if (operation === 'getAll') { const returnAll = this.getNodeParameter('returnAll', i); const filters = this.getNodeParameter('filters', i, {}); const endpoint = `/${entityType}`; const qs = {}; if (filters.where) { if (typeof filters.where === 'string') { try { qs.where = JSON.parse(filters.where); } catch (e) { throw new n8n_workflow_1.NodeOperationError(this.getNode(), `Invalid JSON in 'where' parameter: ${e.message}`); } } else { qs.where = filters.where; } } if (filters.orderBy) { qs.orderBy = filters.orderBy; } if (filters.order) { qs.order = filters.order; } if (filters.select) { qs.select = filters.select; } if (returnAll === true) { const responseData = await GenericFunctions_1.espoApiRequestAllItems.call(this, 'GET', endpoint, {}, qs); returnData.push(...responseData); } else { const limit = this.getNodeParameter('limit', i); qs.maxSize = limit; const responseData = await GenericFunctions_1.espoApiRequest.call(this, 'GET', endpoint, {}, qs); returnData.push(...responseData.list); } } else if (operation === 'update') { const recordId = this.getNodeParameter('recordId', i); const dataToSend = {}; const fields = this.getNodeParameter('fieldsUi.fieldValues', i, []); for (const field of fields) { dataToSend[field.fieldName] = field.fieldValue; } const endpoint = `/${entityType}/${recordId}`; const responseData = await GenericFunctions_1.espoApiRequest.call(this, 'PATCH', endpoint, dataToSend); returnData.push(responseData); } else if (operation === 'delete') { const recordId = this.getNodeParameter('recordId', i); const endpoint = `/${entityType}/${recordId}`; await GenericFunctions_1.espoApiRequest.call(this, 'DELETE', endpoint, {}); returnData.push({ success: true, id: recordId, entityType, }); } } else { const handler = HandlerFactory_1.HandlerFactory.getHandler(resource); let responseData; if (resource === 'attachment' && operation === 'upload') { responseData = await handler.create.call(this, i); returnData.push(responseData); break; } switch (operation) { case 'create': responseData = await handler.create.call(this, i); returnData.push(responseData); break; case 'get': responseData = await handler.get.call(this, i); returnData.push(responseData); break; case 'update': responseData = await handler.update.call(this, i); returnData.push(responseData); break; case 'delete': responseData = await handler.delete.call(this, i); returnData.push(responseData); break; case 'getAll': responseData = await handler.getAll.call(this, i); returnData.push(...responseData); break; default: throw new n8n_workflow_1.NodeOperationError(this.getNode(), `The operation "${operation}" is not supported for resource type "${resource}"`); } } } catch (error) { if (this.continueOnFail()) { returnData.push({ error: error.message }); continue; } throw error; } } return [this.helpers.returnJsonArray(returnData)]; } } exports.EspoCRM = EspoCRM; //# sourceMappingURL=EspoCRM.node.js.map