UNPKG

n8n-nodes-exact-online-v1

Version:

Exact Online Community node for n8n

856 lines 50.1 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.ExactOnline = void 0; const n8n_workflow_1 = require("n8n-workflow"); const GenericFunctions_1 = require("./GenericFunctions"); const fast_xml_parser_1 = require("fast-xml-parser"); const xmlParserOptions = { ignoreAttributes: false, attributeNamePrefix: '@_', allowBooleanAttributes: true, parseTagValue: true, trimValues: true, }; class ExactOnline { constructor() { this.description = { displayName: 'Exact Online', name: 'exactOnline', group: ['transform'], icon: 'file:exactOnline.svg', version: 1, description: 'Exact Online API node', defaults: { name: 'Exact Online', }, inputs: ['main'], outputs: ['main'], credentials: [ { name: 'exactOnlineApi', required: true, displayOptions: { show: { authentication: ['accessToken'], }, }, }, { name: 'exactOnlineApiOAuth2Api', required: true, displayOptions: { show: { authentication: ['oAuth2'], }, }, }, ], properties: [ { displayName: 'Authentication', name: 'authentication', type: 'options', options: [ { name: 'Access Token', value: 'accessToken', }, { name: 'OAuth2', value: 'oAuth2', }, ], default: 'oAuth2', }, { displayName: 'Division Name or ID', name: 'division', type: 'options', typeOptions: { loadOptionsMethod: 'getDivisions', }, default: '', description: 'Division to get data from. Choose from the list, or specify an ID using an <a href="https://docs.n8n.io/code-examples/expressions/">expression</a>.', }, { displayName: 'Service Name or ID', name: 'service', type: 'options', typeOptions: { loadOptionsDependsOn: ['division'], loadOptionsMethod: 'getServices', }, default: '', description: 'Service to connecto to. Choose from the list, or specify an ID using an <a href="https://docs.n8n.io/code-examples/expressions/">expression</a>.', }, { displayName: 'Resource Name or ID', name: 'resource', type: 'options', typeOptions: { loadOptionsDependsOn: ['service'], loadOptionsMethod: 'getResources', }, default: '', description: 'Resource to connect to. Choose from the list, or specify an ID using an <a href="https://docs.n8n.io/code-examples/expressions/">expression</a>.', }, { displayName: 'Operation Name or ID', name: 'operation', type: 'options', typeOptions: { loadOptionsDependsOn: ['resource'], loadOptionsMethod: 'getOperations', }, default: '', description: 'Operation to use. Choose from the list, or specify an ID using an <a href="https://docs.n8n.io/code-examples/expressions/">expression</a>.', }, { displayName: 'ID', name: 'id', type: 'string', default: '', description: 'ID of record', displayOptions: { show: { operation: ['get', 'put', 'delete'], }, }, }, { displayName: 'Parent ID', name: 'parentId', type: 'string', default: '', required: true, description: 'The GUID ID of the parent resource (e.g., BankEntry ID when using BankEntryLines)', displayOptions: { show: { operation: ['getAllViaParentId'], }, }, }, { displayName: 'Limit', name: 'limit', type: 'number', typeOptions: { minValue: 1, }, default: 60, description: 'Max number of results to return', displayOptions: { show: { operation: ['getAll', 'getAllViaParentId'], }, }, }, { displayName: 'Selected Fields Are Excluded', name: 'excludeSelection', type: 'boolean', default: false, description: 'Whether the selected fields are excluded instead of included. Select nothing to retrieve all fields.', displayOptions: { show: { operation: ['getAll', 'getAllViaParentId'], }, }, }, { displayName: 'Disable waiting for minutely rate limit', name: 'ignoreRateLimit', type: 'boolean', default: false, description: 'When set to true, the node will not wait for the minutely rate limit to reset which will result in 429 errors when exceeding the rate-limit.', displayOptions: { show: { operation: ['getAll', 'getAllViaParentId'], }, }, }, { displayName: 'Fields to Get', name: 'selectedFields', type: 'multiOptions', typeOptions: { loadOptionsDependsOn: ['service', 'resource', 'operation'], loadOptionsMethod: 'getFields', }, default: [], description: 'Fields to retrieve from Exact Online. Choose from the list, or specify IDs using an <a href="https://docs.n8n.io/code-examples/expressions/">expression</a>.', displayOptions: { show: { operation: ['getAll', 'getAllViaParentId'], }, }, }, { displayName: 'Conjunction', name: 'conjunction', type: 'options', options: [ { name: 'And', value: 'and', }, { name: 'Or', value: 'or', }, ], default: 'and', description: 'Conjunction to use in filter', displayOptions: { show: { operation: ['getAll'], }, }, }, { displayName: 'Filter', name: 'filter', placeholder: 'Add filter', type: 'fixedCollection', typeOptions: { loadOptionsDependsOn: ['service', 'resource', 'operation'], multipleValues: true, sortable: true, }, default: {}, displayOptions: { show: { operation: ['getAll', 'getAllViaParentId'], }, }, options: [ { name: 'filter', displayName: 'Filter', values: [ { displayName: 'Field Name or ID', name: 'field', type: 'options', typeOptions: { loadOptionsMethod: 'getFieldsFilter', }, default: '', description: 'Field name to filter. Choose from the list, or specify an ID using an <a href="https://docs.n8n.io/code-examples/expressions/">expression</a>.', }, { displayName: 'Operator', name: 'operator', type: 'options', options: [ { name: 'Equal', value: 'eq', }, { name: 'Greater Than', value: 'gt', }, { name: 'Greater than or Equal', value: 'ge', }, { name: 'Less Than', value: 'lt', }, { name: 'Less than or Equal', value: 'le', }, { name: 'Not Equal', value: 'ne', }, { name: 'Contains', value: 'contains', }, ], default: 'eq', description: 'Operator to use in filter', }, { displayName: 'Value', name: 'value', type: 'string', default: '', description: "Value to apply in the filter. For the 'Equal' operator, you can pass an array of strings (e.g., using an expression `{{ $json.myArray }}`) to filter for multiple values (behaves like SQL's IN).", }, ], }, ], }, { displayName: 'Manual JSON Body', name: 'useManualBody', type: 'boolean', default: false, displayOptions: { show: { operation: ['post', 'put'], }, }, }, { displayName: 'JSON Body', name: 'manualBody', type: 'string', default: '', displayOptions: { show: { operation: ['post', 'put'], useManualBody: [true], }, }, }, { displayName: 'Field Data', name: 'data', placeholder: 'Add field data', type: 'fixedCollection', typeOptions: { loadOptionsDependsOn: ['service', 'resource', 'operation'], multipleValues: true, sortable: true, }, default: {}, displayOptions: { show: { operation: ['post', 'put'], useManualBody: [false], }, }, options: [ { name: 'field', displayName: 'Field', values: [ { displayName: 'Field Name or ID', name: 'fieldName', type: 'options', typeOptions: { loadOptionsMethod: 'getFieldsData', }, default: '', description: 'Field name to include in item. Choose from the list, or specify an ID using an expression.', }, { displayName: 'Field Value', name: 'fieldValue', type: 'json', default: '', description: 'Value for the field to add/edit. Can be a string, number, boolean, or JSON object/array for complex types like MatchSets.', }, ], }, ], }, ], }; this.methods = { loadOptions: { async getDivisions() { const currentDivision = await GenericFunctions_1.getCurrentDivision.call(this); const divisions = await GenericFunctions_1.exactOnlineApiRequest.call(this, 'GET', `/api/v1/${currentDivision}/system/Divisions`); return (0, GenericFunctions_1.toDivisionOptions)(divisions.body.d.results); }, async getServices() { const services = (await GenericFunctions_1.getServiceOptions.call(this)); return (0, GenericFunctions_1.toOptionsFromStringArray)([...new Set(services)]); }, async getResources() { const service = this.getNodeParameter('service', 0); const resources = (await GenericFunctions_1.getResourceOptions.call(this, service)); return (0, GenericFunctions_1.toOptionsFromStringArray)(resources); }, async getOperations() { const service = this.getNodeParameter('service', 0); const resource = this.getNodeParameter('resource', 0); const endpointConfig = (await GenericFunctions_1.getEndpointConfig.call(this, service, resource)); if (!endpointConfig) { return []; } const methods = endpointConfig.methods.map((x) => x.toLowerCase()); if (methods.includes('get')) { methods.push('getAll'); } if (endpointConfig.parentResource) { methods.push('getAllViaParentId'); } return (0, GenericFunctions_1.toOptionsFromStringArray)(methods); }, async getFields() { const service = this.getNodeParameter('service', 0); const resource = this.getNodeParameter('resource', 0); const endpointConfig = (await GenericFunctions_1.getEndpointConfig.call(this, service, resource)); const fields = await GenericFunctions_1.getFields.call(this, endpointConfig); return (0, GenericFunctions_1.toFieldSelectOptions)(fields.map((x) => ({ name: x }))); }, async getFieldsFilter() { const service = this.getNodeParameter('service', 0); const resource = this.getNodeParameter('resource', 0); const endpointConfig = (await GenericFunctions_1.getEndpointConfig.call(this, service, resource)); const fields = endpointConfig.fields; return (0, GenericFunctions_1.toFieldFilterOptions)(fields); }, async getFieldsData() { const service = this.getNodeParameter('service', 0); const resource = this.getNodeParameter('resource', 0); const endpointConfig = (await GenericFunctions_1.getEndpointConfig.call(this, service, resource)); const exclude = [ 'Created', 'Creator', 'CreatorFullName', 'Modified', 'Modifier', 'ModifierFullName', ]; const fields = endpointConfig.fields.filter((x) => !exclude.includes(x.name)); return (0, GenericFunctions_1.toFieldFilterOptions)(fields); }, }, }; } async execute() { const items = this.getInputData(); let returnData = []; const length = items.length; let responseData; const division = this.getNodeParameter('division', 0, ''); const service = this.getNodeParameter('service', 0, ''); const resource = this.getNodeParameter('resource', 0, ''); const operation = this.getNodeParameter('operation', 0, ''); const endpointConfig = await GenericFunctions_1.getEndpointConfig.call(this, service, resource); if (!endpointConfig) { throw new n8n_workflow_1.NodeOperationError(this.getNode(), `Configuration not found for service '${service}' and resource '${resource}'.`, { itemIndex: 0 }); } const apiType = endpointConfig.apiType; const uri = endpointConfig.uri.replace('{division}', division); const excludeSelection = this.getNodeParameter('excludeSelection', 0, false); const selectedFields = this.getNodeParameter('selectedFields', 0, []); let onlyNotSelectedFields = []; if (apiType === 'rest' && excludeSelection) { const allFields = await GenericFunctions_1.getFields.call(this, endpointConfig); onlyNotSelectedFields = allFields.filter((x) => !selectedFields.includes(x)); } for (let itemIndex = 0; itemIndex < length; itemIndex++) { try { if (apiType === 'xml') { if (operation === 'post') { let xmlBody = ''; const fieldDefinitions = endpointConfig.fields || []; const dataFields = this.getNodeParameter('data.field', itemIndex, []); const mainFieldDef = fieldDefinitions.length > 0 ? fieldDefinitions[0] : null; let mainFieldName = null; let matchSets = []; if (mainFieldDef) { mainFieldName = mainFieldDef.name; const mainFieldData = dataFields.find((df) => df.fieldName === mainFieldName); if (!mainFieldData || mainFieldData.fieldValue === undefined || mainFieldData.fieldValue === null || mainFieldData.fieldValue === '') { if (mainFieldDef.mandatory) { throw new n8n_workflow_1.NodeOperationError(this.getNode(), `The mandatory '${mainFieldName}' field is missing or empty in Field Data.`, { itemIndex }); } else { throw new n8n_workflow_1.NodeOperationError(this.getNode(), `The field '${mainFieldName}' is missing or empty in Field Data.`, { itemIndex }); } } if (mainFieldName === 'MatchSets') { try { const rawFieldValue = mainFieldData.fieldValue; if (!Array.isArray(rawFieldValue)) { const valueType = typeof rawFieldValue; let receivedValuePreview = JSON.stringify(rawFieldValue); if (receivedValuePreview.length > 100) { receivedValuePreview = receivedValuePreview.substring(0, 100) + '...'; } throw new n8n_workflow_1.NodeOperationError(this.getNode(), `'${mainFieldName}' field value must be a JSON array. Received type '${valueType}' with value: ${receivedValuePreview}`, { itemIndex }); } matchSets = rawFieldValue; } catch (e) { throw new n8n_workflow_1.NodeOperationError(this.getNode(), `Invalid data provided for '${mainFieldName}' field: ${e.message}`, { itemIndex }); } if (matchSets.length === 0) { throw new n8n_workflow_1.NodeOperationError(this.getNode(), `No valid data found in the provided '${mainFieldName}' array.`, { itemIndex }); } xmlBody = (0, GenericFunctions_1.createReconciliationXml)(matchSets); } else { throw new n8n_workflow_1.NodeOperationError(this.getNode(), `XML construction logic not implemented for field '${mainFieldName}'.`, { itemIndex }); } } else { throw new n8n_workflow_1.NodeOperationError(this.getNode(), `No field definitions found for endpoint '${endpointConfig.endpoint}'. Cannot determine primary field for XML construction.`, { itemIndex }); } try { const response = await GenericFunctions_1.exactOnlineXmlRequest.call(this, division, endpointConfig.endpoint, xmlBody); const responseBody = response.body; const parser = new fast_xml_parser_1.XMLParser(xmlParserOptions); let parsedResponse = null; try { const parsedResult = parser.parse(responseBody); if (typeof parsedResult === 'object' && parsedResult !== null) { parsedResponse = parsedResult; } else { throw new Error('Parsed XML is not a valid object'); } } catch (parseError) { const errorMessage = parseError instanceof Error ? parseError.message : String(parseError); throw new n8n_workflow_1.NodeOperationError(this.getNode(), `Failed to parse XML response: ${errorMessage}\nRaw Response: ${responseBody}`, { itemIndex }); } if (!parsedResponse) { throw new n8n_workflow_1.NodeOperationError(this.getNode(), `Failed to parse XML or parsed result was null.\nRaw Response: ${responseBody}`, { itemIndex }); } if (response.statusCode === 200) { const eExact = parsedResponse === null || parsedResponse === void 0 ? void 0 : parsedResponse['eExact']; const messagesObj = eExact === null || eExact === void 0 ? void 0 : eExact['Messages']; const messages = messagesObj === null || messagesObj === void 0 ? void 0 : messagesObj['Message']; let processedMessages = []; if (messages) { const messageArray = Array.isArray(messages) ? messages : [messages]; processedMessages = messageArray.map(msg => msg); } const errorMessages = processedMessages.filter((msg) => String(msg === null || msg === void 0 ? void 0 : msg['@_type']) === '0' || String(msg === null || msg === void 0 ? void 0 : msg['@_type']) === '3' || String(msg === null || msg === void 0 ? void 0 : msg['@_type']) === '4'); const successMessages = processedMessages.filter((msg) => String(msg === null || msg === void 0 ? void 0 : msg['@_type']) !== '0' && String(msg === null || msg === void 0 ? void 0 : msg['@_type']) !== '3' && String(msg === null || msg === void 0 ? void 0 : msg['@_type']) !== '4'); if (errorMessages.length > 0) { const errorDescriptions = errorMessages .map((msg) => (msg === null || msg === void 0 ? void 0 : msg.Description) || 'Unknown error') .join('; '); throw new n8n_workflow_1.NodeOperationError(this.getNode(), `Exact Online reported errors: ${errorDescriptions}\nRaw Response: ${responseBody}`, { itemIndex }); } if (endpointConfig.endpoint === 'MatchSets' && mainFieldName === 'MatchSets') { if (processedMessages.length !== matchSets.length) { throw new n8n_workflow_1.NodeOperationError(this.getNode(), `Mismatch in expected vs received messages. Expected ${matchSets.length}, received ${processedMessages.length}. Response might indicate partial success or unexpected errors.\nRaw Response: ${responseBody}`, { itemIndex }); } } returnData.push({ success: true, message: `XML operation '${endpointConfig.endpoint}' completed. Messages: ${successMessages.map((msg) => msg.Description).join('; ')}`, response: parsedResponse, }); } else { let errorMessage = 'Unknown error'; const eExact = parsedResponse === null || parsedResponse === void 0 ? void 0 : parsedResponse['eExact']; const messagesObj = eExact === null || eExact === void 0 ? void 0 : eExact['Messages']; const messages = messagesObj === null || messagesObj === void 0 ? void 0 : messagesObj['Message']; let processedMessages = []; if (messages) { const messageArray = Array.isArray(messages) ? messages : [messages]; processedMessages = messageArray.map(msg => msg); const errorDesc = processedMessages .map((msg) => msg.Description) .filter(Boolean) .join('; '); if (errorDesc) { errorMessage = errorDesc; } else if (typeof responseBody === 'string') { errorMessage = responseBody; } } else if (typeof responseBody === 'string') { errorMessage = responseBody; } throw new n8n_workflow_1.NodeOperationError(this.getNode(), `XML operation '${endpointConfig.endpoint}' failed: ${response.statusCode} - ${errorMessage}`, { itemIndex }); } } catch (error) { if (error instanceof n8n_workflow_1.NodeOperationError) throw error; throw new n8n_workflow_1.NodeOperationError(this.getNode(), `XML operation '${endpointConfig.endpoint}' failed: ${error.message}`, { itemIndex }); } } else { throw new n8n_workflow_1.NodeOperationError(this.getNode(), `Operation '${operation}' not supported for XML endpoint '${endpointConfig.endpoint}'.`, { itemIndex }); } } else { switch (operation) { case 'get': { const qs = {}; const id = this.getNodeParameter('id', itemIndex, ''); if (id !== '') { qs['$filter'] = `ID eq guid'${id}'`; qs['$top'] = 1; responseData = await GenericFunctions_1.getData.call(this, uri, {}, qs); returnData = returnData.concat(responseData); } break; } case 'getAll': { const qs = {}; const limit = this.getNodeParameter('limit', itemIndex, 0); const conjunction = this.getNodeParameter('conjunction', itemIndex, 'and'); const filter = this.getNodeParameter('filter.filter', itemIndex, 0); const ignoreRateLimit = this.getNodeParameter('ignoreRateLimit', 0, false); if (excludeSelection) { qs['$select'] = onlyNotSelectedFields.join(','); } else if (selectedFields.length > 0) { qs['$select'] = selectedFields.join(','); } const filters = []; if (filter.length > 0) { for (let filterIndex = 0; filterIndex < filter.length; filterIndex++) { const fieldName = filter[filterIndex].field; const operator = filter[filterIndex].operator; const rawValue = filter[filterIndex].value; const fieldType = await GenericFunctions_1.getFieldType.call(this, endpointConfig, fieldName); let filterSegment = ''; if (operator === 'eq' && Array.isArray(rawValue)) { if (rawValue.length === 0) { filterSegment = '1 eq 0'; } else { switch (fieldType) { case 'Edm.Guid': filterSegment = rawValue .map((id) => `${fieldName} eq guid'${id}'`) .join(' or '); break; case 'Edm.String': filterSegment = rawValue .map((val) => `${fieldName} eq '${val}'`) .join(' or '); break; default: const firstValueStr = String(rawValue[0]); if (fieldType === 'Edm.Guid') { filterSegment = `${fieldName} eq guid'${firstValueStr}'`; } else if (fieldType === 'Edm.String') { filterSegment = `${fieldName} eq '${firstValueStr}'`; } else filterSegment = `${fieldName} eq ${firstValueStr}`; break; } } } else { const valueStr = String(rawValue); switch (fieldType) { case 'Edm.String': const opStr = operator === 'contains' ? `substringof('${valueStr}', ${fieldName})` : `${fieldName} ${operator} '${valueStr}'`; filterSegment = opStr; break; case 'Edm.Guid': if (operator === 'eq' || operator === 'ne') { filterSegment = `${fieldName} ${operator} guid'${valueStr}'`; } else { filterSegment = `${fieldName} eq guid'${valueStr}'`; } break; case 'Edm.DateTime': filterSegment = `${fieldName} ${operator} datetime'${valueStr}'`; break; case 'Edm.Boolean': filterSegment = `${fieldName} ${operator} ${valueStr.toLowerCase() === 'true'}`; break; case 'Edm.Int16': case 'Edm.Int32': case 'Edm.Int64': case 'Edm.Double': case 'Edm.Decimal': case 'Edm.Byte': filterSegment = `${fieldName} ${operator} ${valueStr}`; break; default: filterSegment = `${fieldName} ${operator} '${valueStr}'`; break; } } if (filterSegment) { filters.push(filterSegment); } } if (filters.length > 0) qs['$filter'] = filters.join(` ${conjunction} `); } responseData = await GenericFunctions_1.getAllData.call(this, uri, limit, {}, qs, {}, ignoreRateLimit); returnData = returnData.concat(responseData); break; } case 'getAllViaParentId': { const parentId = this.getNodeParameter('parentId', itemIndex, ''); const limit = this.getNodeParameter('limit', itemIndex, 60); const ignoreRateLimit = this.getNodeParameter('ignoreRateLimit', 0, false); if (!endpointConfig.parentResource) { throw new n8n_workflow_1.NodeOperationError(this.getNode(), `Operation 'getAllViaParentId' is not supported for resource '${resource}' as it lacks a defined parent resource in the configuration.`, { itemIndex }); } if (parentId === '') { throw new n8n_workflow_1.NodeOperationError(this.getNode(), 'Parent ID is required for the getAllViaParentId operation.', { itemIndex }); } const parentResource = endpointConfig.parentResource; const specificUri = `/api/v1/${division}/${service}/${parentResource}(guid'${parentId}')/${resource}`; responseData = await GenericFunctions_1.getAllData.call(this, specificUri, limit, {}, {}, {}, ignoreRateLimit); returnData = returnData.concat(responseData); break; } case 'post': { let body = {}; const useManualBodyRest = this.getNodeParameter('useManualBody', itemIndex, false); if (useManualBodyRest) { const manualBody = this.getNodeParameter('manualBody', itemIndex, {}); if (!manualBody) { throw new n8n_workflow_1.NodeOperationError(this.getNode(), `Please include the fields and values for the item you want to create.`, { itemIndex }); } body = manualBody; } else { const data = this.getNodeParameter('data.field', itemIndex, 0); if (!data) { throw new n8n_workflow_1.NodeOperationError(this.getNode(), `Please include the fields and values for the item you want to create.`, { itemIndex }); } const fieldsEntered = data.map((x) => x.fieldName); const mandatoryFields = (await GenericFunctions_1.getMandatoryFields.call(this, endpointConfig)); const mandatoryFieldsNotIncluded = mandatoryFields.filter((x) => !fieldsEntered.includes(x)); if (mandatoryFieldsNotIncluded.length > 0) { throw new n8n_workflow_1.NodeOperationError(this.getNode(), `The following fields are mandatory and did not get used: '${mandatoryFieldsNotIncluded.join(', ')}'`, { itemIndex }); } if (data.length > 0) { for (let dataIndex = 0; dataIndex < data.length; dataIndex++) { const fieldName = data[dataIndex].fieldName; const fieldType = await GenericFunctions_1.getFieldType.call(this, endpointConfig, fieldName); const fieldValue = data[dataIndex].fieldValue; switch (fieldType) { case 'Edm.String': case 'Edm.Guid': case 'Edm.DateTime': body[`${fieldName}`] = fieldValue; break; case 'Edm.Boolean': body[`${fieldName}`] = fieldValue.toLocaleLowerCase() === 'true'; break; case 'Edm.Int16': case 'Edm.Int32': case 'Edm.Int64': case 'Edm.Double': case 'Edm.Decimal': case 'Edm.Byte': body[`${fieldName}`] = +fieldValue; break; default: break; } } } } responseData = await GenericFunctions_1.exactOnlineApiRequest.call(this, 'Post', uri, body, {}, { headers: { Prefer: 'return=representation' } }); returnData = returnData.concat(responseData.body.d); break; } case 'put': { const id = this.getNodeParameter('id', itemIndex, ''); if (id === '') { throw new n8n_workflow_1.NodeOperationError(this.getNode(), `Please enter an Id of a record to edit.`, { itemIndex }); } let body = {}; const useManualBodyRest = this.getNodeParameter('useManualBody', itemIndex, false); if (useManualBodyRest) { const manualBody = this.getNodeParameter('manualBody', itemIndex, {}); if (!manualBody) { throw new n8n_workflow_1.NodeOperationError(this.getNode(), `Please include the fields and values for the item you want to edit.`, { itemIndex }); } body = manualBody; } else { const data = this.getNodeParameter('data.field', itemIndex, 0); if (!data) { throw new n8n_workflow_1.NodeOperationError(this.getNode(), `Please include the fields and values for the item you want to edit.`, { itemIndex }); } if (data.length > 0) { for (let dataIndex = 0; dataIndex < data.length; dataIndex++) { const fieldName = data[dataIndex].fieldName; const fieldType = await GenericFunctions_1.getFieldType.call(this, endpointConfig, fieldName); const fieldValue = data[dataIndex].fieldValue; switch (fieldType) { case 'Edm.String': case 'Edm.Guid': case 'Edm.DateTime': body[`${fieldName}`] = fieldValue; break; case 'Edm.Boolean': body[`${fieldName}`] = fieldValue.toLocaleLowerCase() === 'true'; break; case 'Edm.Int16': case 'Edm.Int32': case 'Edm.Int64': case 'Edm.Double': case 'Edm.Decimal': case 'Edm.Byte': body[`${fieldName}`] = +fieldValue; break; default: break; } } } } const uriWithId = `${uri}(guid'${id}')`; responseData = await GenericFunctions_1.exactOnlineApiRequest.call(this, 'Put', uriWithId, body, {}); if (responseData.statusCode === 204) { returnData = returnData.concat({ msg: 'Succesfully changed field values.' }); } else { throw new n8n_workflow_1.NodeOperationError(this.getNode(), `Something went wrong.`, { itemIndex, }); } break; } case 'delete': { const id = this.getNodeParameter('id', itemIndex, ''); if (id === '') { throw new n8n_workflow_1.NodeOperationError(this.getNode(), `Please enter an Id of a record to delete.`, { itemIndex }); } const uriWithId = `${uri}(guid'${id}')`; responseData = await GenericFunctions_1.exactOnlineApiRequest.call(this, 'Delete', uriWithId, {}, {}); if (responseData.statusCode === 204) { returnData = returnData.concat({ msg: 'Succesfully Deleted record.' }); } else { throw new n8n_workflow_1.NodeOperationError(this.getNode(), `Something went wrong.`, { itemIndex, }); } break; } default: { throw new n8n_workflow_1.NodeOperationError(this.getNode(), `Operation '${operation}' is not supported for REST API endpoint '${endpointConfig.endpoint}'.`, { itemIndex }); } } } } catch (error) { if (this.continueOnFail()) { returnData.push({ error }); } else { if (error.context) { error.context.itemIndex = itemIndex; throw error; } throw new n8n_workflow_1.NodeOperationError(this.getNode(), error, { itemIndex, }); } } } return [this.helpers.returnJsonArray(returnData)