n8n-nodes-innotes 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (31) hide show
  1. package/README.md +305 -0
  2. package/dist/credentials/InNotesApi.credentials.js +108 -0
  3. package/dist/credentials/InNotesApi.credentials.js.map +1 -0
  4. package/dist/credentials/InNotesApi.credentials.ts +111 -0
  5. package/dist/credentials/Logo_128.png +0 -0
  6. package/dist/descriptions/ContactDescription.js +291 -0
  7. package/dist/descriptions/ContactDescription.js.map +1 -0
  8. package/dist/descriptions/JobDescription.js +413 -0
  9. package/dist/descriptions/JobDescription.js.map +1 -0
  10. package/dist/descriptions/NoteDescription.js +130 -0
  11. package/dist/descriptions/NoteDescription.js.map +1 -0
  12. package/dist/descriptions/StatusDescription.js +78 -0
  13. package/dist/descriptions/StatusDescription.js.map +1 -0
  14. package/dist/descriptions/TagDescription.js +34 -0
  15. package/dist/descriptions/TagDescription.js.map +1 -0
  16. package/dist/descriptions/UserDescription.js +40 -0
  17. package/dist/descriptions/UserDescription.js.map +1 -0
  18. package/dist/icons/Logo_128.png +0 -0
  19. package/dist/nodes/InNotes/InNotes.node.js +679 -0
  20. package/dist/nodes/InNotes/InNotes.node.js.map +1 -0
  21. package/dist/nodes/InNotes/Logo_128.png +0 -0
  22. package/dist/package.json +70 -0
  23. package/dist/test/InNotes.node.test.js +144 -0
  24. package/dist/test/InNotes.node.test.js.map +1 -0
  25. package/dist/test/setup.js +38 -0
  26. package/dist/test/setup.js.map +1 -0
  27. package/dist/types/InNotesTypes.js +8 -0
  28. package/dist/types/InNotesTypes.js.map +1 -0
  29. package/dist/utils/helpers.js +172 -0
  30. package/dist/utils/helpers.js.map +1 -0
  31. package/package.json +70 -0
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../nodes/InNotes/InNotes.node.ts"],"names":[],"mappings":"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","file":"InNotes.node.js","sourcesContent":["/**\n * @author Marco Visin\n * @date 2025-06-02\n */\n\nimport {\n\tIDataObject,\n\tIExecuteFunctions,\n\tIHttpRequestMethods,\n\tILoadOptionsFunctions,\n\tINodeExecutionData,\n\tINodePropertyOptions,\n\tINodeType,\n\tINodeTypeDescription,\n\tNodeApiError,\n\tNodeConnectionType,\n} from 'n8n-workflow';\n\nimport {contactFields, contactOperations} from '../../descriptions/ContactDescription';\nimport {noteFields, noteOperations} from '../../descriptions/NoteDescription';\nimport {jobFields, jobOperations} from '../../descriptions/JobDescription';\nimport {statusFields, statusOperations} from '../../descriptions/StatusDescription';\nimport {tagFields, tagOperations} from '../../descriptions/TagDescription';\nimport {userFields, userOperations} from '../../descriptions/UserDescription';\n\nexport class InNotes implements INodeType {\n\tdescription: INodeTypeDescription = {\n\t\tdisplayName: 'InNotes',\n\t\tname: 'inNotes',\n\t\ticon: 'file:Logo_128.png',\n\t\tgroup: ['output'],\n\t\tversion: 1,\n\t\tsubtitle: '={{$parameter[\"operation\"] + \": \" + $parameter[\"resource\"]}}',\n\t\tdescription: 'Consume InNotes CRM API',\n\t\tdefaults: {\n\t\t\tname: 'InNotes',\n\t\t},\n\t\tinputs: [NodeConnectionType.Main],\n\t\toutputs: [NodeConnectionType.Main],\n\t\tcredentials: [\n\t\t\t{\n\t\t\t\tname: 'inNotesApi',\n\t\t\t\trequired: true,\n\t\t\t},\n\t\t],\n\t\tproperties: [\n\t\t\t{\n\t\t\t\tdisplayName: 'Resource',\n\t\t\t\tname: 'resource',\n\t\t\t\ttype: 'options',\n\t\t\t\tnoDataExpression: true,\n\t\t\t\toptions: [\n\t\t\t\t\t{\n\t\t\t\t\t\tname: 'Contact',\n\t\t\t\t\t\tvalue: 'contact',\n\t\t\t\t\t},\n\t\t\t\t\t{\n\t\t\t\t\t\tname: 'Note',\n\t\t\t\t\t\tvalue: 'note',\n\t\t\t\t\t},\n\t\t\t\t\t{\n\t\t\t\t\t\tname: 'Job',\n\t\t\t\t\t\tvalue: 'job',\n\t\t\t\t\t},\n\t\t\t\t\t{\n\t\t\t\t\t\tname: 'Status',\n\t\t\t\t\t\tvalue: 'status',\n\t\t\t\t\t},\n\t\t\t\t\t{\n\t\t\t\t\t\tname: 'Tag',\n\t\t\t\t\t\tvalue: 'tag',\n\t\t\t\t\t},\n\t\t\t\t\t{\n\t\t\t\t\t\tname: 'User',\n\t\t\t\t\t\tvalue: 'user',\n\t\t\t\t\t},\n\t\t\t\t],\n\t\t\t\tdefault: 'contact',\n\t\t\t},\n\t\t\t...contactOperations,\n\t\t\t...noteOperations,\n\t\t\t...jobOperations,\n\t\t\t...statusOperations,\n\t\t\t...tagOperations,\n\t\t\t...userOperations,\n\t\t\t...contactFields,\n\t\t\t...noteFields,\n\t\t\t...jobFields,\n\t\t\t...statusFields,\n\t\t\t...tagFields,\n\t\t\t...userFields,\n\t\t],\n\t};\n\n\tmethods = {\n\t\tloadOptions: {\n\t\t\tasync jobStatuses(this: ILoadOptionsFunctions): Promise<INodePropertyOptions[]> {\n\t\t\t\ttry {\n\t\t\t\t\tconst credentials = await this.getCredentials('inNotesApi');\n\t\t\t\t\tconst baseUrl = credentials.baseUrl as string;\n\n\t\t\t\t\tconst response = await this.helpers.httpRequestWithAuthentication.call(\n\t\t\t\t\t\tthis,\n\t\t\t\t\t\t'inNotesApi',\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tmethod: 'GET' as IHttpRequestMethods,\n\t\t\t\t\t\t\turl: `${baseUrl}/api/statuses`,\n\t\t\t\t\t\t\tqs: { type: 'job' },\n\t\t\t\t\t\t\theaders: {\n\t\t\t\t\t\t\t\tAccept: 'application/json',\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t},\n\t\t\t\t\t);\n\n\t\t\t\t\tconst statuses = Array.isArray(response) ? response : [response];\n\t\t\t\t\treturn statuses.map((status: any) => ({\n\t\t\t\t\t\tname: status.name,\n\t\t\t\t\t\tvalue: status.name,\n\t\t\t\t\t}));\n\t\t\t\t} catch (error) {\n\t\t\t\t\tthrow new NodeApiError(this.getNode(), {\n\t\t\t\t\t\tmessage: `Failed to load job statuses: ${(error as Error).message}`,\n\t\t\t\t\t});\n\t\t\t\t}\n\t\t\t},\n\t\t},\n\t};\n\n\tasync execute(this: IExecuteFunctions): Promise<INodeExecutionData[][]> {\n\t\tconst items = this.getInputData();\n\t\tconst returnData: IDataObject[] = [];\n\t\tconst resource = this.getNodeParameter('resource', 0);\n\t\tconst operation = this.getNodeParameter('operation', 0);\n\n\t\t// Create a node instance to access the methods\n\t\tconst nodeInstance = new InNotes();\n\n\t\tfor (let i = 0; i < items.length; i++) {\n\t\t\ttry {\n\t\t\t\tlet responseData: IDataObject | IDataObject[] = {};\n\n\t\t\t\tif (resource === 'contact') {\n\t\t\t\t\tresponseData = await nodeInstance.executeContactOperation(this, i, operation);\n\t\t\t\t} else if (resource === 'note') {\n\t\t\t\t\tresponseData = await nodeInstance.executeNoteOperation(this, i, operation);\n\t\t\t\t} else if (resource === 'job') {\n\t\t\t\t\tresponseData = await nodeInstance.executeJobOperation(this, i, operation);\n\t\t\t\t} else if (resource === 'status') {\n\t\t\t\t\tresponseData = await nodeInstance.executeStatusOperation(this, i, operation);\n\t\t\t\t} else if (resource === 'tag') {\n\t\t\t\t\tresponseData = await nodeInstance.executeTagOperation(this, i, operation);\n\t\t\t\t} else if (resource === 'user') {\n\t\t\t\t\tresponseData = await nodeInstance.executeUserOperation(this, i, operation);\n\t\t\t\t}\n\n\t\t\t\tif (Array.isArray(responseData)) {\n\t\t\t\t\treturnData.push(...responseData);\n\t\t\t\t} else {\n\t\t\t\t\treturnData.push(responseData);\n\t\t\t\t}\n\t\t\t} catch (error) {\n\t\t\t\tif (this.continueOnFail()) {\n\t\t\t\t\treturnData.push({ error: (error as Error).message });\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\t\t\t\tthrow error;\n\t\t\t}\n\t\t}\n\n\t\treturn [this.helpers.returnJsonArray(returnData)];\n\t}\n\n\tprivate async executeContactOperation(executeFunctions: IExecuteFunctions, itemIndex: number, operation: string): Promise<IDataObject | IDataObject[]> {\n\t\tconst credentials = await executeFunctions.getCredentials('inNotesApi');\n\t\tconst baseUrl = credentials.baseUrl as string;\n\n\t\tif (operation === 'create') {\n\t\t\tconst name = executeFunctions.getNodeParameter('name', itemIndex) as string;\n\t\t\tconst linkedin_key = executeFunctions.getNodeParameter('linkedin_key', itemIndex) as string;\n\t\t\tconst linkedin_user = executeFunctions.getNodeParameter('linkedin_user', itemIndex, '') as string;\n\t\t\tconst location = executeFunctions.getNodeParameter('location', itemIndex, '') as string;\n\t\t\tconst current_company = executeFunctions.getNodeParameter('current_company', itemIndex, '') as string;\n\t\t\tconst picture_url = executeFunctions.getNodeParameter('picture_url', itemIndex, '') as string;\n\t\t\tconst tags = executeFunctions.getNodeParameter('tags', itemIndex, '') as string;\n\t\t\tconst status_id = executeFunctions.getNodeParameter('status_id', itemIndex, '') as string;\n\n\t\t\tconst body: IDataObject = {\n\t\t\t\tname,\n\t\t\t\tlinkedin_key,\n\t\t\t\t...(linkedin_user && { linkedin_user }),\n\t\t\t\t...(location && { location }),\n\t\t\t\t...(current_company && { current_company }),\n\t\t\t\t...(picture_url && { picture_url }),\n\t\t\t\t...(tags && { tags: tags.split(',').map((tag: string) => tag.trim()) }),\n\t\t\t\t...(status_id && { status_id }),\n\t\t\t};\n\n\t\t\tconst response = await executeFunctions.helpers.httpRequestWithAuthentication.call(\n\t\t\t\texecuteFunctions,\n\t\t\t\t'inNotesApi',\n\t\t\t\t{\n\t\t\t\t\tmethod: 'POST' as IHttpRequestMethods,\n\t\t\t\t\turl: `${baseUrl}/api/contacts`,\n\t\t\t\t\tbody,\n\t\t\t\t\theaders: {\n\t\t\t\t\t\tAccept: 'application/json',\n\t\t\t\t\t\t'Content-Type': 'application/json',\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t);\n\n\t\t\treturn response;\n\t\t}\n\n\t\tif (operation === 'get') {\n\t\t\tconst contactId = executeFunctions.getNodeParameter('contactId', itemIndex) as string;\n\n\t\t\tconst response = await executeFunctions.helpers.httpRequestWithAuthentication.call(\n\t\t\t\texecuteFunctions,\n\t\t\t\t'inNotesApi',\n\t\t\t\t{\n\t\t\t\t\tmethod: 'GET' as IHttpRequestMethods,\n\t\t\t\t\turl: `${baseUrl}/api/contacts/${contactId}`,\n\t\t\t\t\theaders: {\n\t\t\t\t\t\tAccept: 'application/json',\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t);\n\n\t\t\treturn response;\n\t\t}\n\n\t\tif (operation === 'getAll') {\n\t\t\tconst returnAll = executeFunctions.getNodeParameter('returnAll', itemIndex, false) as boolean;\n\t\t\tconst search = executeFunctions.getNodeParameter('search', itemIndex, '') as string;\n\t\t\tconst tags = executeFunctions.getNodeParameter('tags', itemIndex, '') as string;\n\n\t\t\tconst qs: IDataObject = {};\n\t\t\tif (search) qs.search = search;\n\t\t\tif (tags) qs.tags = tags;\n\n\t\t\tif (!returnAll) {\n\t\t\t\tconst limit = executeFunctions.getNodeParameter('limit', itemIndex, 24);\n\t\t\t\tqs.pageSize = limit;\n\t\t\t\tqs.page = 1;\n\t\t\t}\n\n\t\t\tconst response = await executeFunctions.helpers.httpRequestWithAuthentication.call(\n\t\t\t\texecuteFunctions,\n\t\t\t\t'inNotesApi',\n\t\t\t\t{\n\t\t\t\t\tmethod: 'GET' as IHttpRequestMethods,\n\t\t\t\t\turl: `${baseUrl}/api/contacts`,\n\t\t\t\t\tqs,\n\t\t\t\t\theaders: {\n\t\t\t\t\t\tAccept: 'application/json',\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t);\n\n\t\t\treturn Array.isArray(response) ? response : [response];\n\t\t}\n\n\t\tif (operation === 'update') {\n\t\t\tconst contactId = executeFunctions.getNodeParameter('contactId', itemIndex) as string;\n\t\t\tconst updateFields = executeFunctions.getNodeParameter('updateFields', itemIndex);\n\n\t\t\tconst response = await executeFunctions.helpers.httpRequestWithAuthentication.call(\n\t\t\t\texecuteFunctions,\n\t\t\t\t'inNotesApi',\n\t\t\t\t{\n\t\t\t\t\tmethod: 'PUT' as IHttpRequestMethods,\n\t\t\t\t\turl: `${baseUrl}/api/contacts/${contactId}`,\n\t\t\t\t\tbody: updateFields,\n\t\t\t\t\theaders: {\n\t\t\t\t\t\tAccept: 'application/json',\n\t\t\t\t\t\t'Content-Type': 'application/json',\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t);\n\n\t\t\treturn response;\n\t\t}\n\n\t\tif (operation === 'delete') {\n\t\t\tconst contactId = executeFunctions.getNodeParameter('contactId', itemIndex) as string;\n\n\t\t\tawait executeFunctions.helpers.httpRequestWithAuthentication.call(\n\t\t\t\texecuteFunctions,\n\t\t\t\t'inNotesApi',\n\t\t\t\t{\n\t\t\t\t\tmethod: 'DELETE' as IHttpRequestMethods,\n\t\t\t\t\turl: `${baseUrl}/api/contacts/${contactId}`,\n\t\t\t\t\theaders: {\n\t\t\t\t\t\tAccept: 'application/json',\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t);\n\n\t\t\treturn { success: true };\n\t\t}\n\n\t\tthrow new NodeApiError(executeFunctions.getNode(), {\n\t\t\tmessage: `The operation \"${operation}\" is not supported for resource \"contact\"!`,\n\t\t});\n\t}\n\n\tprivate async executeNoteOperation(executeFunctions: IExecuteFunctions, itemIndex: number, operation: string): Promise<IDataObject | IDataObject[]> {\n\t\tconst credentials = await executeFunctions.getCredentials('inNotesApi');\n\t\tconst baseUrl = credentials.baseUrl as string;\n\n\t\tif (operation === 'create') {\n\t\t\tconst content = executeFunctions.getNodeParameter('content', itemIndex) as string;\n\t\t\tconst contactId = executeFunctions.getNodeParameter('contactId', itemIndex) as string | number;\n\t\t\tconst visibility = executeFunctions.getNodeParameter('visibility', itemIndex, '') as string;\n\t\t\tconst ext_table_name = executeFunctions.getNodeParameter('ext_table_name', itemIndex, '') as string;\n\n\t\t\tconst body: IDataObject = {\n\t\t\t\tcontent,\n\t\t\t\tcontact_id: contactId,\n\t\t\t\t...(visibility && { visibility }),\n\t\t\t\t...(ext_table_name && { ext_table_name }),\n\t\t\t};\n\n\t\t\tconst response = await executeFunctions.helpers.httpRequestWithAuthentication.call(\n\t\t\t\texecuteFunctions,\n\t\t\t\t'inNotesApi',\n\t\t\t\t{\n\t\t\t\t\tmethod: 'POST' as IHttpRequestMethods,\n\t\t\t\t\turl: `${baseUrl}/api/note`,\n\t\t\t\t\tbody,\n\t\t\t\t\theaders: {\n\t\t\t\t\t\tAccept: 'application/json',\n\t\t\t\t\t\t'Content-Type': 'application/json',\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t);\n\n\t\t\treturn response;\n\t\t}\n\n\t\tif (operation === 'get') {\n\t\t\tconst noteId = executeFunctions.getNodeParameter('noteId', itemIndex) as string | number;\n\n\t\t\tconst response = await executeFunctions.helpers.httpRequestWithAuthentication.call(\n\t\t\t\texecuteFunctions,\n\t\t\t\t'inNotesApi',\n\t\t\t\t{\n\t\t\t\t\tmethod: 'GET' as IHttpRequestMethods,\n\t\t\t\t\turl: `${baseUrl}/api/note/${noteId}`,\n\t\t\t\t\theaders: {\n\t\t\t\t\t\tAccept: 'application/json',\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t);\n\n\t\t\treturn response;\n\t\t}\n\n\t\tif (operation === 'getAll') {\n\t\t\tconst contactId = executeFunctions.getNodeParameter('contactId', itemIndex) as string | number;\n\t\t\tconst returnAll = executeFunctions.getNodeParameter('returnAll', itemIndex, false) as boolean;\n\n\t\t\tconst qs: IDataObject = {\n\t\t\t\tcontact_id: contactId,\n\t\t\t};\n\n\t\t\tif (!returnAll) {\n\t\t\t\tconst limit = executeFunctions.getNodeParameter('limit', itemIndex, 24);\n\t\t\t\tqs.pageSize = limit;\n\t\t\t\tqs.page = 1;\n\t\t\t}\n\n\t\t\tconst response = await executeFunctions.helpers.httpRequestWithAuthentication.call(\n\t\t\t\texecuteFunctions,\n\t\t\t\t'inNotesApi',\n\t\t\t\t{\n\t\t\t\t\tmethod: 'GET' as IHttpRequestMethods,\n\t\t\t\t\turl: `${baseUrl}/api/note`,\n\t\t\t\t\tqs,\n\t\t\t\t\theaders: {\n\t\t\t\t\t\tAccept: 'application/json',\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t);\n\n\t\t\treturn Array.isArray(response) ? response : [response];\n\t\t}\n\n\t\tif (operation === 'update') {\n\t\t\tconst noteId = executeFunctions.getNodeParameter('noteId', itemIndex) as string | number;\n\t\t\tconst updateFields = executeFunctions.getNodeParameter('updateFields', itemIndex);\n\n\t\t\tconst response = await executeFunctions.helpers.httpRequestWithAuthentication.call(\n\t\t\t\texecuteFunctions,\n\t\t\t\t'inNotesApi',\n\t\t\t\t{\n\t\t\t\t\tmethod: 'PUT' as IHttpRequestMethods,\n\t\t\t\t\turl: `${baseUrl}/api/note/${noteId}`,\n\t\t\t\t\tbody: updateFields,\n\t\t\t\t\theaders: {\n\t\t\t\t\t\tAccept: 'application/json',\n\t\t\t\t\t\t'Content-Type': 'application/json',\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t);\n\n\t\t\treturn response;\n\t\t}\n\n\t\tif (operation === 'delete') {\n\t\t\tconst noteId = executeFunctions.getNodeParameter('noteId', itemIndex) as string | number;\n\n\t\t\tawait executeFunctions.helpers.httpRequestWithAuthentication.call(\n\t\t\t\texecuteFunctions,\n\t\t\t\t'inNotesApi',\n\t\t\t\t{\n\t\t\t\t\tmethod: 'DELETE' as IHttpRequestMethods,\n\t\t\t\t\turl: `${baseUrl}/api/note/${noteId}`,\n\t\t\t\t\theaders: {\n\t\t\t\t\t\tAccept: 'application/json',\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t);\n\n\t\t\treturn { success: true };\n\t\t}\n\n\t\tthrow new NodeApiError(executeFunctions.getNode(), {\n\t\t\tmessage: `The operation \"${operation}\" is not supported for resource \"note\"!`,\n\t\t});\n\t}\n\n\tprivate async executeJobOperation(executeFunctions: IExecuteFunctions, itemIndex: number, operation: string): Promise<IDataObject | IDataObject[]> {\n\t\tconst credentials = await executeFunctions.getCredentials('inNotesApi');\n\t\tconst baseUrl = credentials.baseUrl as string;\n\n\t\tif (operation === 'create') {\n\t\t\tconst title = executeFunctions.getNodeParameter('title', itemIndex) as string;\n\t\t\tconst contactId = executeFunctions.getNodeParameter('contactId', itemIndex) as string | number;\n\t\t\tconst company = executeFunctions.getNodeParameter('company', itemIndex) as string;\n\t\t\tconst status = executeFunctions.getNodeParameter('status', itemIndex, '') as string;\n\t\t\tconst description = executeFunctions.getNodeParameter('description', itemIndex, '') as string;\n\t\t\tconst location = executeFunctions.getNodeParameter('location', itemIndex, '') as string;\n\t\t\tconst remote_setting = executeFunctions.getNodeParameter('remote_setting', itemIndex, '') as string;\n\t\t\tconst company_url = executeFunctions.getNodeParameter('company_url', itemIndex, '') as string;\n\t\t\tconst ext_id = executeFunctions.getNodeParameter('ext_id', itemIndex, '') as string;\n\t\t\tconst picture_url = executeFunctions.getNodeParameter('picture_url', itemIndex, '') as string;\n\t\t\tconst tags = executeFunctions.getNodeParameter('tags', itemIndex, '') as string;\n\n\t\t\tlet status_id: string | undefined;\n\n\t\t\t// If status is provided, lookup the status ID\n\t\t\tif (status) {\n\t\t\t\ttry {\n\t\t\t\t\t// Get all job statuses\n\t\t\t\t\tconst statusResponse = await executeFunctions.helpers.httpRequestWithAuthentication.call(\n\t\t\t\t\t\texecuteFunctions,\n\t\t\t\t\t\t'inNotesApi',\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tmethod: 'GET' as IHttpRequestMethods,\n\t\t\t\t\t\t\turl: `${baseUrl}/api/statuses`,\n\t\t\t\t\t\t\tqs: { type: 'job' },\n\t\t\t\t\t\t\theaders: {\n\t\t\t\t\t\t\t\tAccept: 'application/json',\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t},\n\t\t\t\t\t);\n\n\t\t\t\t\t// Find matching status by name (case-insensitive)\n\t\t\t\t\tconst statuses = Array.isArray(statusResponse) ? statusResponse : [statusResponse];\n\t\t\t\t\tconst matchingStatus = statuses.find((s: any) =>\n\t\t\t\t\t\ts.name && s.name.toLowerCase() === status.toLowerCase(),\n\t\t\t\t\t);\n\n\t\t\t\t\tif (matchingStatus) {\n\t\t\t\t\t\tstatus_id = matchingStatus.id.toString();\n\t\t\t\t\t} else {\n\t\t\t\t\t\tthrow new NodeApiError(executeFunctions.getNode(), {\n\t\t\t\t\t\t\tmessage: `Status \"${status}\" not found. Available statuses: ${statuses.map((s: any) => s.name).join(', ')}`,\n\t\t\t\t\t\t});\n\t\t\t\t\t}\n\t\t\t\t} catch (error) {\n\t\t\t\t\tif (error instanceof NodeApiError) {\n\t\t\t\t\t\tthrow error;\n\t\t\t\t\t}\n\t\t\t\t\tthrow new NodeApiError(executeFunctions.getNode(), {\n\t\t\t\t\t\tmessage: `Failed to lookup status \"${status}\": ${(error as Error).message}`,\n\t\t\t\t\t});\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tconst body: IDataObject = {\n\t\t\t\ttitle,\n\t\t\t\tcontact_id: contactId,\n\t\t\t\tcompany,\n\t\t\t\tstatus,\n\t\t\t\t...(description && { description }),\n\t\t\t\t...(location && { location }),\n\t\t\t\t...(remote_setting && { remote_setting }),\n\t\t\t\t...(company_url && { company_url }),\n\t\t\t\t...(status_id && { status_id }),\n\t\t\t\t...(ext_id && { ext_id }),\n\t\t\t\t...(picture_url && { picture_url }),\n\t\t\t\t...(tags && { tags: tags.split(',').map((tag: string) => tag.trim()) }),\n\t\t\t};\n\n\t\t\tconst response = await executeFunctions.helpers.httpRequestWithAuthentication.call(\n\t\t\t\texecuteFunctions,\n\t\t\t\t'inNotesApi',\n\t\t\t\t{\n\t\t\t\t\tmethod: 'POST' as IHttpRequestMethods,\n\t\t\t\t\turl: `${baseUrl}/api/job`,\n\t\t\t\t\tbody,\n\t\t\t\t\theaders: {\n\t\t\t\t\t\tAccept: 'application/json',\n\t\t\t\t\t\t'Content-Type': 'application/json',\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t);\n\n\t\t\treturn response;\n\t\t}\n\n\t\tif (operation === 'get') {\n\t\t\tconst jobId = executeFunctions.getNodeParameter('jobId', itemIndex) as string | number;\n\n\t\t\tconst response = await executeFunctions.helpers.httpRequestWithAuthentication.call(\n\t\t\t\texecuteFunctions,\n\t\t\t\t'inNotesApi',\n\t\t\t\t{\n\t\t\t\t\tmethod: 'GET' as IHttpRequestMethods,\n\t\t\t\t\turl: `${baseUrl}/api/job/${jobId}`,\n\t\t\t\t\theaders: {\n\t\t\t\t\t\tAccept: 'application/json',\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t);\n\n\t\t\treturn response;\n\t\t}\n\n\t\tif (operation === 'getAll') {\n\t\t\tconst returnAll = executeFunctions.getNodeParameter('returnAll', itemIndex, false) as boolean;\n\t\t\tconst search = executeFunctions.getNodeParameter('search', itemIndex, '') as string;\n\t\t\tconst tags = executeFunctions.getNodeParameter('tags', itemIndex, '') as string;\n\n\t\t\tconst qs: IDataObject = {};\n\t\t\tif (search) qs.search = search;\n\t\t\tif (tags) qs.tags = tags;\n\n\t\t\tif (!returnAll) {\n\t\t\t\tconst limit = executeFunctions.getNodeParameter('limit', itemIndex, 24);\n\t\t\t\tqs.pageSize = limit;\n\t\t\t\tqs.page = 1;\n\t\t\t}\n\n\t\t\tconst response = await executeFunctions.helpers.httpRequestWithAuthentication.call(\n\t\t\t\texecuteFunctions,\n\t\t\t\t'inNotesApi',\n\t\t\t\t{\n\t\t\t\t\tmethod: 'GET' as IHttpRequestMethods,\n\t\t\t\t\turl: `${baseUrl}/api/job`,\n\t\t\t\t\tqs,\n\t\t\t\t\theaders: {\n\t\t\t\t\t\tAccept: 'application/json',\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t);\n\n\t\t\treturn Array.isArray(response) ? response : [response];\n\t\t}\n\n\t\tif (operation === 'update') {\n\t\t\tconst jobId = executeFunctions.getNodeParameter('jobId', itemIndex) as string | number;\n\t\t\tconst updateFields = executeFunctions.getNodeParameter('updateFields', itemIndex);\n\n\t\t\t// Handle status string lookup if provided\n\t\t\tif (updateFields.status && typeof updateFields.status === 'string') {\n\t\t\t\ttry {\n\t\t\t\t\t// Get all job statuses\n\t\t\t\t\tconst statusResponse = await executeFunctions.helpers.httpRequestWithAuthentication.call(\n\t\t\t\t\t\texecuteFunctions,\n\t\t\t\t\t\t'inNotesApi',\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tmethod: 'GET' as IHttpRequestMethods,\n\t\t\t\t\t\t\turl: `${baseUrl}/api/statuses`,\n\t\t\t\t\t\t\tqs: { type: 'job' },\n\t\t\t\t\t\t\theaders: {\n\t\t\t\t\t\t\t\tAccept: 'application/json',\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t},\n\t\t\t\t\t);\n\n\t\t\t\t\t// Find matching status by name (case-insensitive)\n\t\t\t\t\tconst statuses = Array.isArray(statusResponse) ? statusResponse : [statusResponse];\n\t\t\t\t\tconst matchingStatus = statuses.find((s: any) =>\n\t\t\t\t\t\ts.name && s.name.toLowerCase() === (updateFields.status as string).toLowerCase(),\n\t\t\t\t\t);\n\n\t\t\t\t\tif (matchingStatus) {\n\t\t\t\t\t\t// Replace status with status_id and remove status field\n\t\t\t\t\t\tupdateFields.status_id = matchingStatus.id.toString();\n\t\t\t\t\t\tdelete updateFields.status;\n\t\t\t\t\t} else {\n\t\t\t\t\t\tthrow new NodeApiError(executeFunctions.getNode(), {\n\t\t\t\t\t\t\tmessage: `Status \"${updateFields.status}\" not found. Available statuses: ${statuses.map((s: any) => s.name).join(', ')}`,\n\t\t\t\t\t\t});\n\t\t\t\t\t}\n\t\t\t\t} catch (error) {\n\t\t\t\t\tif (error instanceof NodeApiError) {\n\t\t\t\t\t\tthrow error;\n\t\t\t\t\t}\n\t\t\t\t\tthrow new NodeApiError(executeFunctions.getNode(), {\n\t\t\t\t\t\tmessage: `Failed to lookup status \"${updateFields.status}\": ${(error as Error).message}`,\n\t\t\t\t\t});\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// Process tags if provided as comma-separated string\n\t\t\tif (updateFields.tags && typeof updateFields.tags === 'string') {\n\t\t\t\tupdateFields.tags = (updateFields.tags).split(',').map((tag: string) => tag.trim());\n\t\t\t}\n\n\t\t\tconst response = await executeFunctions.helpers.httpRequestWithAuthentication.call(\n\t\t\t\texecuteFunctions,\n\t\t\t\t'inNotesApi',\n\t\t\t\t{\n\t\t\t\t\tmethod: 'PUT' as IHttpRequestMethods,\n\t\t\t\t\turl: `${baseUrl}/api/job/${jobId}`,\n\t\t\t\t\tbody: updateFields,\n\t\t\t\t\theaders: {\n\t\t\t\t\t\tAccept: 'application/json',\n\t\t\t\t\t\t'Content-Type': 'application/json',\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t);\n\n\t\t\treturn response;\n\t\t}\n\n\t\tif (operation === 'delete') {\n\t\t\tconst jobId = executeFunctions.getNodeParameter('jobId', itemIndex) as string | number;\n\n\t\t\tawait executeFunctions.helpers.httpRequestWithAuthentication.call(\n\t\t\t\texecuteFunctions,\n\t\t\t\t'inNotesApi',\n\t\t\t\t{\n\t\t\t\t\tmethod: 'DELETE' as IHttpRequestMethods,\n\t\t\t\t\turl: `${baseUrl}/api/job/${jobId}`,\n\t\t\t\t\theaders: {\n\t\t\t\t\t\tAccept: 'application/json',\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t);\n\n\t\t\treturn { success: true };\n\t\t}\n\n\t\tif (operation === 'search') {\n\t\t\tconst searchQuery = executeFunctions.getNodeParameter('searchQuery', itemIndex) as string;\n\t\t\tconst searchOptions = executeFunctions.getNodeParameter('searchOptions', itemIndex, {}) as IDataObject;\n\n\t\t\tconst qs: IDataObject = {\n\t\t\t\tsearch: searchQuery,\n\t\t\t};\n\n\t\t\t// Add optional search parameters\n\t\t\tif (searchOptions.location) qs.location = searchOptions.location;\n\t\t\tif (searchOptions.company) qs.company = searchOptions.company;\n\t\t\tif (searchOptions.remote_setting) qs.remote_setting = searchOptions.remote_setting;\n\t\t\tif (searchOptions.status) qs.status = searchOptions.status;\n\t\t\tif (searchOptions.tags) qs.tags = searchOptions.tags;\n\n\t\t\t// Set limit with default value\n\t\t\tconst limit = (searchOptions.limit as number) || 24;\n\t\t\tqs.pageSize = limit;\n\t\t\tqs.page = 1;\n\n\t\t\tconst response = await executeFunctions.helpers.httpRequestWithAuthentication.call(\n\t\t\t\texecuteFunctions,\n\t\t\t\t'inNotesApi',\n\t\t\t\t{\n\t\t\t\t\tmethod: 'GET' as IHttpRequestMethods,\n\t\t\t\t\turl: `${baseUrl}/api/job`,\n\t\t\t\t\tqs,\n\t\t\t\t\theaders: {\n\t\t\t\t\t\tAccept: 'application/json',\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t);\n\n\t\t\treturn Array.isArray(response) ? response : [response];\n\t\t}\n\n\t\tthrow new NodeApiError(executeFunctions.getNode(), {\n\t\t\tmessage: `The operation \"${operation}\" is not supported for resource \"job\"!`,\n\t\t});\n\t}\n\n\tprivate async executeStatusOperation(executeFunctions: IExecuteFunctions, itemIndex: number, operation: string): Promise<IDataObject | IDataObject[]> {\n\t\tconst credentials = await executeFunctions.getCredentials('inNotesApi');\n\t\tconst baseUrl = credentials.baseUrl as string;\n\n\t\tif (operation === 'create') {\n\t\t\tconst name = executeFunctions.getNodeParameter('name', itemIndex) as string;\n\t\t\tconst type = executeFunctions.getNodeParameter('type', itemIndex) as string;\n\t\t\tconst color = executeFunctions.getNodeParameter('color', itemIndex, '') as string;\n\n\t\t\tconst body: IDataObject = {\n\t\t\t\tname,\n\t\t\t\ttype,\n\t\t\t\t...(color && { color }),\n\t\t\t};\n\n\t\t\tconst response = await executeFunctions.helpers.httpRequestWithAuthentication.call(\n\t\t\t\texecuteFunctions,\n\t\t\t\t'inNotesApi',\n\t\t\t\t{\n\t\t\t\t\tmethod: 'POST' as IHttpRequestMethods,\n\t\t\t\t\turl: `${baseUrl}/api/statuses`,\n\t\t\t\t\tbody,\n\t\t\t\t\theaders: {\n\t\t\t\t\t\tAccept: 'application/json',\n\t\t\t\t\t\t'Content-Type': 'application/json',\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t);\n\n\t\t\treturn response;\n\t\t}\n\n\t\tif (operation === 'getAll') {\n\t\t\tconst type = executeFunctions.getNodeParameter('type', itemIndex, 'contact') as string;\n\n\t\t\tconst response = await executeFunctions.helpers.httpRequestWithAuthentication.call(\n\t\t\t\texecuteFunctions,\n\t\t\t\t'inNotesApi',\n\t\t\t\t{\n\t\t\t\t\tmethod: 'GET' as IHttpRequestMethods,\n\t\t\t\t\turl: `${baseUrl}/api/statuses`,\n\t\t\t\t\tqs: { type },\n\t\t\t\t\theaders: {\n\t\t\t\t\t\tAccept: 'application/json',\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t);\n\n\t\t\treturn Array.isArray(response) ? response : [response];\n\t\t}\n\n\t\tif (operation === 'update') {\n\t\t\tconst statusId = executeFunctions.getNodeParameter('statusId', itemIndex) as string | number;\n\t\t\tconst updateFields = executeFunctions.getNodeParameter('updateFields', itemIndex);\n\n\t\t\tconst response = await executeFunctions.helpers.httpRequestWithAuthentication.call(\n\t\t\t\texecuteFunctions,\n\t\t\t\t'inNotesApi',\n\t\t\t\t{\n\t\t\t\t\tmethod: 'PUT' as IHttpRequestMethods,\n\t\t\t\t\turl: `${baseUrl}/api/statuses/${statusId}`,\n\t\t\t\t\tbody: updateFields,\n\t\t\t\t\theaders: {\n\t\t\t\t\t\tAccept: 'application/json',\n\t\t\t\t\t\t'Content-Type': 'application/json',\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t);\n\n\t\t\treturn response;\n\t\t}\n\n\t\tif (operation === 'delete') {\n\t\t\tconst statusId = executeFunctions.getNodeParameter('statusId', itemIndex) as string | number;\n\n\t\t\tawait executeFunctions.helpers.httpRequestWithAuthentication.call(\n\t\t\t\texecuteFunctions,\n\t\t\t\t'inNotesApi',\n\t\t\t\t{\n\t\t\t\t\tmethod: 'DELETE' as IHttpRequestMethods,\n\t\t\t\t\turl: `${baseUrl}/api/statuses/${statusId}`,\n\t\t\t\t\theaders: {\n\t\t\t\t\t\tAccept: 'application/json',\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t);\n\n\t\t\treturn { success: true };\n\t\t}\n\n\t\tthrow new NodeApiError(executeFunctions.getNode(), {\n\t\t\tmessage: `The operation \"${operation}\" is not supported for resource \"status\"!`,\n\t\t});\n\t}\n\n\tprivate async executeTagOperation(executeFunctions: IExecuteFunctions, _itemIndex: number, operation: string): Promise<IDataObject | IDataObject[]> {\n\t\tconst credentials = await executeFunctions.getCredentials('inNotesApi');\n\t\tconst baseUrl = credentials.baseUrl as string;\n\n\t\tif (operation === 'getAll') {\n\t\t\tconst response = await executeFunctions.helpers.httpRequestWithAuthentication.call(\n\t\t\t\texecuteFunctions,\n\t\t\t\t'inNotesApi',\n\t\t\t\t{\n\t\t\t\t\tmethod: 'GET' as IHttpRequestMethods,\n\t\t\t\t\turl: `${baseUrl}/api/tags`,\n\t\t\t\t\theaders: {\n\t\t\t\t\t\tAccept: 'application/json',\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t);\n\n\t\t\treturn Array.isArray(response) ? response : [response];\n\t\t}\n\n\t\tthrow new NodeApiError(executeFunctions.getNode(), {\n\t\t\tmessage: `The operation \"${operation}\" is not supported for resource \"tag\"! Supported operations: getAll`,\n\t\t});\n\t}\n\n\tprivate async executeUserOperation(executeFunctions: IExecuteFunctions, itemIndex: number, operation: string): Promise<IDataObject | IDataObject[]> {\n\t\tconst credentials = await executeFunctions.getCredentials('inNotesApi');\n\t\tconst baseUrl = credentials.baseUrl as string;\n\n\t\tif (operation === 'get') {\n\t\t\tconst response = await executeFunctions.helpers.httpRequestWithAuthentication.call(\n\t\t\t\texecuteFunctions,\n\t\t\t\t'inNotesApi',\n\t\t\t\t{\n\t\t\t\t\tmethod: 'GET' as IHttpRequestMethods,\n\t\t\t\t\turl: `${baseUrl}/api/user`,\n\t\t\t\t\theaders: {\n\t\t\t\t\t\tAccept: 'application/json',\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t);\n\n\t\t\treturn response;\n\t\t}\n\n\t\tif (operation === 'getCv') {\n\t\t\tconst response = await executeFunctions.helpers.httpRequestWithAuthentication.call(\n\t\t\t\texecuteFunctions,\n\t\t\t\t'inNotesApi',\n\t\t\t\t{\n\t\t\t\t\tmethod: 'GET' as IHttpRequestMethods,\n\t\t\t\t\turl: `${baseUrl}/api/user`,\n\t\t\t\t\theaders: {\n\t\t\t\t\t\tAccept: 'application/json',\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t);\n\n\t\t\t// Return only CV-related fields\n\t\t\tconst { cv, job_preferences, cv_updated_at } = response;\n\t\t\treturn {\n\t\t\t\tcv,\n\t\t\t\tjob_preferences,\n\t\t\t\tcv_updated_at,\n\t\t\t};\n\t\t}\n\n\t\tif (operation === 'update') {\n\t\t\tconst updateFields = executeFunctions.getNodeParameter('updateFields', itemIndex);\n\n\t\t\tconst response = await executeFunctions.helpers.httpRequestWithAuthentication.call(\n\t\t\t\texecuteFunctions,\n\t\t\t\t'inNotesApi',\n\t\t\t\t{\n\t\t\t\t\tmethod: 'PUT' as IHttpRequestMethods,\n\t\t\t\t\turl: `${baseUrl}/api/user`,\n\t\t\t\t\tbody: updateFields,\n\t\t\t\t\theaders: {\n\t\t\t\t\t\tAccept: 'application/json',\n\t\t\t\t\t\t'Content-Type': 'application/json',\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t);\n\n\t\t\treturn response;\n\t\t}\n\n\t\tthrow new NodeApiError(executeFunctions.getNode(), {\n\t\t\tmessage: `The operation \"${operation}\" is not supported for resource \"user\"! Supported operations: get, getCv, update`,\n\t\t});\n\t}\n}\n"]}
Binary file
@@ -0,0 +1,70 @@
1
+ {
2
+ "name": "n8n-nodes-innotes",
3
+ "version": "1.0.0",
4
+ "description": "N8N node for InNotes CRM API integration",
5
+ "keywords": [
6
+ "n8n-community-node-package"
7
+ ],
8
+ "license": "MIT",
9
+ "homepage": "https://github.com/mrc527/InNotes/tree/main/n8n_node",
10
+ "author": {
11
+ "name": "Marco Visin",
12
+ "email": "marco@visin.ch"
13
+ },
14
+ "repository": {
15
+ "type": "git",
16
+ "url": "git+https://github.com/mrc527/InNotes.git",
17
+ "directory": "n8n_node"
18
+ },
19
+ "engines": {
20
+ "node": ">=18.10",
21
+ "yarn": ">=1.22.0"
22
+ },
23
+ "packageManager": "yarn@1.22.19",
24
+ "main": "index.js",
25
+ "scripts": {
26
+ "build": "gulp build",
27
+ "dev": "gulp dev",
28
+ "format": "prettier . --write",
29
+ "lint": "eslint . --ext .ts",
30
+ "lintfix": "eslint . --ext .ts --fix",
31
+ "test": "jest",
32
+ "test:watch": "jest --watch",
33
+ "test:coverage": "jest --coverage",
34
+ "prepublishOnly": "yarn build && yarn lint"
35
+ },
36
+ "files": [
37
+ "dist"
38
+ ],
39
+ "n8n": {
40
+ "n8nNodesApiVersion": 1,
41
+ "credentials": [
42
+ "dist/credentials/InNotesApi.credentials.js"
43
+ ],
44
+ "nodes": [
45
+ "dist/nodes/InNotes/InNotes.node.js"
46
+ ]
47
+ },
48
+ "devDependencies": {
49
+ "@types/jest": "^29.5.5",
50
+ "@types/node": "^18.16.16",
51
+ "@typescript-eslint/eslint-plugin": "^6.6.0",
52
+ "@typescript-eslint/parser": "^6.6.0",
53
+ "eslint": "^8.48.0",
54
+ "eslint-plugin-n8n-nodes-base": "^1.16.1",
55
+ "gulp": "^4.0.2",
56
+ "gulp-clean": "^0.4.0",
57
+ "gulp-sourcemaps": "^3.0.0",
58
+ "gulp-typescript": "^6.0.0-alpha.1",
59
+ "jest": "^29.6.4",
60
+ "n8n-core": "*",
61
+ "n8n-workflow": "*",
62
+ "prettier": "^3.0.3",
63
+ "ts-jest": "^29.1.1",
64
+ "typescript": "^5.2.2"
65
+ },
66
+ "peerDependencies": {
67
+ "n8n-core": "*",
68
+ "n8n-workflow": "*"
69
+ }
70
+ }
@@ -0,0 +1,144 @@
1
+ "use strict";
2
+ /**
3
+ * Author: marco
4
+ * Last updated: 2025-05-30
5
+ */
6
+ Object.defineProperty(exports, "__esModule", { value: true });
7
+ const InNotes_node_1 = require("../nodes/InNotes/InNotes.node");
8
+ describe('InNotes Node', () => {
9
+ let node;
10
+ let mockExecuteFunctions;
11
+ beforeEach(() => {
12
+ node = new InNotes_node_1.InNotes();
13
+ mockExecuteFunctions = {
14
+ getInputData: jest.fn().mockReturnValue([{ json: {} }]),
15
+ getNodeParameter: jest.fn(),
16
+ getCredentials: jest.fn().mockResolvedValue({
17
+ username: 'test@example.com',
18
+ password: 'testpassword',
19
+ baseUrl: 'https://test.innotes.com',
20
+ }),
21
+ helpers: {
22
+ httpRequestWithAuthentication: jest.fn(),
23
+ httpRequest: jest.fn(),
24
+ requestWithAuthenticationPaginated: jest.fn(),
25
+ request: jest.fn(),
26
+ requestWithAuthentication: jest.fn(),
27
+ requestOAuth2: jest.fn(),
28
+ requestOAuth1: jest.fn(),
29
+ },
30
+ };
31
+ });
32
+ describe('Node Properties', () => {
33
+ it('should have correct description', () => {
34
+ expect(node.description.displayName).toBe('InNotes');
35
+ expect(node.description.name).toBe('inNotes');
36
+ expect(node.description.group).toEqual(['transform']);
37
+ expect(node.description.version).toBe(1);
38
+ });
39
+ it('should have correct credentials', () => {
40
+ expect(node.description.credentials).toEqual([
41
+ {
42
+ name: 'inNotesApi',
43
+ required: true,
44
+ },
45
+ ]);
46
+ });
47
+ it('should have correct inputs and outputs', () => {
48
+ expect(node.description.inputs).toEqual(['main']);
49
+ expect(node.description.outputs).toEqual(['main']);
50
+ });
51
+ });
52
+ describe('Resource Operations', () => {
53
+ it('should have contact resource with correct operations', () => {
54
+ var _a, _b;
55
+ const contactResource = (_a = node.description.properties) === null || _a === void 0 ? void 0 : _a.find(prop => prop.name === 'resource' && prop.type === 'options');
56
+ expect(contactResource).toBeDefined();
57
+ const contactOption = (_b = contactResource === null || contactResource === void 0 ? void 0 : contactResource.options) === null || _b === void 0 ? void 0 : _b.find((option) => option.value === 'contact');
58
+ expect(contactOption).toBeDefined();
59
+ expect(contactOption.name).toBe('Contact');
60
+ });
61
+ it('should have note resource with correct operations', () => {
62
+ var _a, _b;
63
+ const noteResource = (_a = node.description.properties) === null || _a === void 0 ? void 0 : _a.find(prop => prop.name === 'resource' && prop.type === 'options');
64
+ expect(noteResource).toBeDefined();
65
+ const noteOption = (_b = noteResource === null || noteResource === void 0 ? void 0 : noteResource.options) === null || _b === void 0 ? void 0 : _b.find((option) => option.value === 'note');
66
+ expect(noteOption).toBeDefined();
67
+ expect(noteOption.name).toBe('Note');
68
+ });
69
+ });
70
+ describe('Execute Method', () => {
71
+ it('should handle contact get operation', async () => {
72
+ const mockHttpRequest = jest.fn().mockResolvedValue({
73
+ data: {
74
+ id: 1,
75
+ name: 'Test Contact',
76
+ email: 'test@example.com',
77
+ },
78
+ });
79
+ mockExecuteFunctions.helpers.httpRequestWithAuthentication = mockHttpRequest;
80
+ mockExecuteFunctions.getNodeParameter = jest.fn()
81
+ .mockReturnValueOnce('contact') // resource
82
+ .mockReturnValueOnce('get') // operation
83
+ .mockReturnValueOnce(1); // contactId
84
+ const result = await node.execute.call(mockExecuteFunctions);
85
+ expect(mockHttpRequest).toHaveBeenCalledWith('inNotesApi', expect.objectContaining({
86
+ method: 'GET',
87
+ url: '/api/contacts/1',
88
+ }));
89
+ expect(result).toEqual([
90
+ [
91
+ {
92
+ json: {
93
+ id: 1,
94
+ name: 'Test Contact',
95
+ email: 'test@example.com',
96
+ },
97
+ },
98
+ ],
99
+ ]);
100
+ });
101
+ it('should handle note create operation', async () => {
102
+ const mockHttpRequest = jest.fn().mockResolvedValue({
103
+ data: {
104
+ id: 1,
105
+ content: 'Test note content',
106
+ contactId: 1,
107
+ },
108
+ });
109
+ mockExecuteFunctions.helpers.httpRequestWithAuthentication = mockHttpRequest;
110
+ mockExecuteFunctions.getNodeParameter = jest.fn()
111
+ .mockReturnValueOnce('note') // resource
112
+ .mockReturnValueOnce('create') // operation
113
+ .mockReturnValueOnce('Test note content') // content
114
+ .mockReturnValueOnce(1); // contactId
115
+ const result = await node.execute.call(mockExecuteFunctions);
116
+ expect(mockHttpRequest).toHaveBeenCalledWith('inNotesApi', expect.objectContaining({
117
+ method: 'POST',
118
+ url: '/api/note',
119
+ body: {
120
+ content: 'Test note content',
121
+ contactId: 1,
122
+ },
123
+ }));
124
+ expect(result).toEqual([
125
+ [
126
+ {
127
+ json: {
128
+ id: 1,
129
+ content: 'Test note content',
130
+ contactId: 1,
131
+ },
132
+ },
133
+ ],
134
+ ]);
135
+ });
136
+ it('should throw error for unsupported resource', async () => {
137
+ mockExecuteFunctions.getNodeParameter = jest.fn()
138
+ .mockReturnValueOnce('unsupported'); // resource
139
+ await expect(node.execute.call(mockExecuteFunctions)).rejects.toThrow('The resource "unsupported" is not known!');
140
+ });
141
+ });
142
+ });
143
+
144
+ //# sourceMappingURL=InNotes.node.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../test/InNotes.node.test.ts"],"names":[],"mappings":"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","file":"InNotes.node.test.js","sourcesContent":["/**\n * Author: marco\n * Last updated: 2025-05-30\n */\n\nimport { InNotes } from '../nodes/InNotes/InNotes.node';\nimport { IExecuteFunctions, INodeExecutionData } from 'n8n-workflow';\n\ndescribe('InNotes Node', () => {\n\tlet node: InNotes;\n\tlet mockExecuteFunctions: Partial<IExecuteFunctions>;\n\n\tbeforeEach(() => {\n\t\tnode = new InNotes();\n\t\tmockExecuteFunctions = {\n\t\t\tgetInputData: jest.fn().mockReturnValue([{ json: {} }] as INodeExecutionData[]),\n\t\t\tgetNodeParameter: jest.fn(),\n\t\t\tgetCredentials: jest.fn().mockResolvedValue({\n\t\t\t\tusername: 'test@example.com',\n\t\t\t\tpassword: 'testpassword',\n\t\t\t\tbaseUrl: 'https://test.innotes.com',\n\t\t\t}),\n\t\t\thelpers: {\n\t\t\t\thttpRequestWithAuthentication: jest.fn(),\n\t\t\t\thttpRequest: jest.fn(),\n\t\t\t\trequestWithAuthenticationPaginated: jest.fn(),\n\t\t\t\trequest: jest.fn(),\n\t\t\t\trequestWithAuthentication: jest.fn(),\n\t\t\t\trequestOAuth2: jest.fn(),\n\t\t\t\trequestOAuth1: jest.fn(),\n\t\t\t},\n\t\t} as any;\n\t});\n\n\tdescribe('Node Properties', () => {\n\t\tit('should have correct description', () => {\n\t\t\texpect(node.description.displayName).toBe('InNotes');\n\t\t\texpect(node.description.name).toBe('inNotes');\n\t\t\texpect(node.description.group).toEqual(['transform']);\n\t\t\texpect(node.description.version).toBe(1);\n\t\t});\n\n\t\tit('should have correct credentials', () => {\n\t\t\texpect(node.description.credentials).toEqual([\n\t\t\t\t{\n\t\t\t\t\tname: 'inNotesApi',\n\t\t\t\t\trequired: true,\n\t\t\t\t},\n\t\t\t]);\n\t\t});\n\n\t\tit('should have correct inputs and outputs', () => {\n\t\t\texpect(node.description.inputs).toEqual(['main']);\n\t\t\texpect(node.description.outputs).toEqual(['main']);\n\t\t});\n\t});\n\n\tdescribe('Resource Operations', () => {\n\t\tit('should have contact resource with correct operations', () => {\n\t\t\tconst contactResource = node.description.properties?.find(\n\t\t\t\tprop => prop.name === 'resource' && prop.type === 'options',\n\t\t\t);\n\n\t\t\texpect(contactResource).toBeDefined();\n\t\t\tconst contactOption = (contactResource as any)?.options?.find(\n\t\t\t\t(option: any) => option.value === 'contact',\n\t\t\t);\n\t\t\texpect(contactOption).toBeDefined();\n\t\t\texpect(contactOption.name).toBe('Contact');\n\t\t});\n\n\t\tit('should have note resource with correct operations', () => {\n\t\t\tconst noteResource = node.description.properties?.find(\n\t\t\t\tprop => prop.name === 'resource' && prop.type === 'options',\n\t\t\t);\n\n\t\t\texpect(noteResource).toBeDefined();\n\t\t\tconst noteOption = (noteResource as any)?.options?.find(\n\t\t\t\t(option: any) => option.value === 'note',\n\t\t\t);\n\t\t\texpect(noteOption).toBeDefined();\n\t\t\texpect(noteOption.name).toBe('Note');\n\t\t});\n\t});\n\n\tdescribe('Execute Method', () => {\n\t\tit('should handle contact get operation', async () => {\n\t\t\tconst mockHttpRequest = jest.fn().mockResolvedValue({\n\t\t\t\tdata: {\n\t\t\t\t\tid: 1,\n\t\t\t\t\tname: 'Test Contact',\n\t\t\t\t\temail: 'test@example.com',\n\t\t\t\t},\n\t\t\t});\n\n\t\t\tmockExecuteFunctions.helpers!.httpRequestWithAuthentication = mockHttpRequest;\n\t\t\tmockExecuteFunctions.getNodeParameter = jest.fn()\n\t\t\t\t.mockReturnValueOnce('contact') // resource\n\t\t\t\t.mockReturnValueOnce('get') // operation\n\t\t\t\t.mockReturnValueOnce(1); // contactId\n\n\t\t\tconst result = await node.execute.call(mockExecuteFunctions as IExecuteFunctions);\n\n\t\t\texpect(mockHttpRequest).toHaveBeenCalledWith(\n\t\t\t\t'inNotesApi',\n\t\t\t\texpect.objectContaining({\n\t\t\t\t\tmethod: 'GET',\n\t\t\t\t\turl: '/api/contacts/1',\n\t\t\t\t}),\n\t\t\t);\n\n\t\t\texpect(result).toEqual([\n\t\t\t\t[\n\t\t\t\t\t{\n\t\t\t\t\t\tjson: {\n\t\t\t\t\t\t\tid: 1,\n\t\t\t\t\t\t\tname: 'Test Contact',\n\t\t\t\t\t\t\temail: 'test@example.com',\n\t\t\t\t\t\t},\n\t\t\t\t\t},\n\t\t\t\t],\n\t\t\t]);\n\t\t});\n\n\t\tit('should handle note create operation', async () => {\n\t\t\tconst mockHttpRequest = jest.fn().mockResolvedValue({\n\t\t\t\tdata: {\n\t\t\t\t\tid: 1,\n\t\t\t\t\tcontent: 'Test note content',\n\t\t\t\t\tcontactId: 1,\n\t\t\t\t},\n\t\t\t});\n\n\t\t\tmockExecuteFunctions.helpers!.httpRequestWithAuthentication = mockHttpRequest;\n\t\t\tmockExecuteFunctions.getNodeParameter = jest.fn()\n\t\t\t\t.mockReturnValueOnce('note') // resource\n\t\t\t\t.mockReturnValueOnce('create') // operation\n\t\t\t\t.mockReturnValueOnce('Test note content') // content\n\t\t\t\t.mockReturnValueOnce(1); // contactId\n\n\t\t\tconst result = await node.execute.call(mockExecuteFunctions as IExecuteFunctions);\n\n\t\t\texpect(mockHttpRequest).toHaveBeenCalledWith(\n\t\t\t\t'inNotesApi',\n\t\t\t\texpect.objectContaining({\n\t\t\t\t\tmethod: 'POST',\n\t\t\t\t\turl: '/api/note',\n\t\t\t\t\tbody: {\n\t\t\t\t\t\tcontent: 'Test note content',\n\t\t\t\t\t\tcontactId: 1,\n\t\t\t\t\t},\n\t\t\t\t}),\n\t\t\t);\n\n\t\t\texpect(result).toEqual([\n\t\t\t\t[\n\t\t\t\t\t{\n\t\t\t\t\t\tjson: {\n\t\t\t\t\t\t\tid: 1,\n\t\t\t\t\t\t\tcontent: 'Test note content',\n\t\t\t\t\t\t\tcontactId: 1,\n\t\t\t\t\t\t},\n\t\t\t\t\t},\n\t\t\t\t],\n\t\t\t]);\n\t\t});\n\n\t\tit('should throw error for unsupported resource', async () => {\n\t\t\tmockExecuteFunctions.getNodeParameter = jest.fn()\n\t\t\t\t.mockReturnValueOnce('unsupported'); // resource\n\n\t\t\tawait expect(\n\t\t\t\tnode.execute.call(mockExecuteFunctions as IExecuteFunctions),\n\t\t\t).rejects.toThrow('The resource \"unsupported\" is not known!');\n\t\t});\n\t});\n});\n"]}
@@ -0,0 +1,38 @@
1
+ "use strict";
2
+ /**
3
+ * Author: marco
4
+ * Last updated: 2025-05-30
5
+ */
6
+ // Global test setup
7
+ beforeAll(() => {
8
+ // Setup environment variables for testing
9
+ if (!process.env.NODE_ENV) {
10
+ Object.defineProperty(process.env, 'NODE_ENV', {
11
+ value: 'test',
12
+ writable: true,
13
+ });
14
+ }
15
+ });
16
+ afterAll(() => {
17
+ // Cleanup after all tests
18
+ });
19
+ // Mock N8N core modules
20
+ jest.mock('n8n-workflow', () => ({
21
+ NodeApiError: class NodeApiError extends Error {
22
+ constructor(_node, error, _options) {
23
+ super(error.message || 'API Error');
24
+ this.name = 'NodeApiError';
25
+ }
26
+ },
27
+ NodeOperationError: class NodeOperationError extends Error {
28
+ constructor(_node, error, _options) {
29
+ super(error.message || 'Operation Error');
30
+ this.name = 'NodeOperationError';
31
+ }
32
+ },
33
+ }));
34
+ jest.mock('n8n-core', () => ({
35
+ // Add mock implementations as needed
36
+ }));
37
+
38
+ //# sourceMappingURL=setup.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../test/setup.ts"],"names":[],"mappings":";AAAA;;;GAGG;AAEH,oBAAoB;AACpB,SAAS,CAAC,GAAG,EAAE;IACd,0CAA0C;IAC1C,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,QAAQ,EAAE,CAAC;QAC3B,MAAM,CAAC,cAAc,CAAC,OAAO,CAAC,GAAG,EAAE,UAAU,EAAE;YAC9C,KAAK,EAAE,MAAM;YACb,QAAQ,EAAE,IAAI;SACd,CAAC,CAAC;IACJ,CAAC;AACF,CAAC,CAAC,CAAC;AAEH,QAAQ,CAAC,GAAG,EAAE;IACb,0BAA0B;AAC3B,CAAC,CAAC,CAAC;AAEH,wBAAwB;AACxB,IAAI,CAAC,IAAI,CAAC,cAAc,EAAE,GAAG,EAAE,CAAC,CAAC;IAChC,YAAY,EAAE,MAAM,YAAa,SAAQ,KAAK;QAC7C,YAAY,KAAU,EAAE,KAAU,EAAE,QAAc;YACjD,KAAK,CAAC,KAAK,CAAC,OAAO,IAAI,WAAW,CAAC,CAAC;YACpC,IAAI,CAAC,IAAI,GAAG,cAAc,CAAC;QAC5B,CAAC;KACD;IACD,kBAAkB,EAAE,MAAM,kBAAmB,SAAQ,KAAK;QACzD,YAAY,KAAU,EAAE,KAAU,EAAE,QAAc;YACjD,KAAK,CAAC,KAAK,CAAC,OAAO,IAAI,iBAAiB,CAAC,CAAC;YAC1C,IAAI,CAAC,IAAI,GAAG,oBAAoB,CAAC;QAClC,CAAC;KACD;CACD,CAAC,CAAC,CAAC;AAEJ,IAAI,CAAC,IAAI,CAAC,UAAU,EAAE,GAAG,EAAE,CAAC,CAAC;AAC5B,qCAAqC;CACrC,CAAC,CAAC,CAAC","file":"setup.js","sourcesContent":["/**\n * Author: marco\n * Last updated: 2025-05-30\n */\n\n// Global test setup\nbeforeAll(() => {\n\t// Setup environment variables for testing\n\tif (!process.env.NODE_ENV) {\n\t\tObject.defineProperty(process.env, 'NODE_ENV', {\n\t\t\tvalue: 'test',\n\t\t\twritable: true,\n\t\t});\n\t}\n});\n\nafterAll(() => {\n\t// Cleanup after all tests\n});\n\n// Mock N8N core modules\njest.mock('n8n-workflow', () => ({\n\tNodeApiError: class NodeApiError extends Error {\n\t\tconstructor(_node: any, error: any, _options?: any) {\n\t\t\tsuper(error.message || 'API Error');\n\t\t\tthis.name = 'NodeApiError';\n\t\t}\n\t},\n\tNodeOperationError: class NodeOperationError extends Error {\n\t\tconstructor(_node: any, error: any, _options?: any) {\n\t\t\tsuper(error.message || 'Operation Error');\n\t\t\tthis.name = 'NodeOperationError';\n\t\t}\n\t},\n}));\n\njest.mock('n8n-core', () => ({\n\t// Add mock implementations as needed\n}));\n"]}
@@ -0,0 +1,8 @@
1
+ "use strict";
2
+ /**
3
+ * @author Marco Visin
4
+ * @date 2025-05-30
5
+ */
6
+ Object.defineProperty(exports, "__esModule", { value: true });
7
+
8
+ //# sourceMappingURL=InNotesTypes.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../types/InNotesTypes.ts"],"names":[],"mappings":";AAAA;;;GAGG","file":"InNotesTypes.js","sourcesContent":["/**\n * @author Marco Visin\n * @date 2025-05-30\n */\n\nexport type InNotesResourceType =\n\t| 'contact'\n\t| 'note'\n\t| 'job'\n\t| 'status'\n\t| 'tag'\n\t| 'user';\n\nexport type InNotesOperationType =\n\t| 'create'\n\t| 'get'\n\t| 'getAll'\n\t| 'update'\n\t| 'delete';\n\nexport interface IContact {\n\tid?: string;\n\tname?: string;\n\tlinkedin_key?: string;\n\tlinkedin_user?: string;\n\tlocation?: string;\n\tcurrent_company?: string;\n\tpicture_url?: string;\n\ttags?: string[];\n\tstatus_id?: string;\n\tcreated_at?: string;\n\tupdated_at?: string;\n}\n\nexport interface INote {\n\tid?: string;\n\tuser_id?: string;\n\text_id?: string;\n\text_table_name?: string;\n\ttext?: string;\n\tvisibility?: 'private' | 'public';\n\tflagColor?: string;\n\tcreated_at?: string;\n\tupdated_at?: string;\n}\n\nexport interface IJob {\n\tid?: string;\n\text_id?: string;\n\tname?: string;\n\tcompany_name?: string;\n\tlocation?: string;\n\tdescription?: string;\n\tremote_setting?: string;\n\tpicture_url?: string;\n\tcompany_url?: string;\n\tstatus_id?: string;\n\ttags?: string[];\n\tcreated_at?: string;\n\tupdated_at?: string;\n}\n\nexport interface IStatus {\n\tid?: string;\n\tuser_id?: string;\n\tname?: string;\n\ttype?: 'contact' | 'job';\n\tcreated_at?: string;\n}\n\nexport interface IUser {\n\tid?: string;\n\tname?: string;\n\tusername?: string;\n\temail?: string;\n\tstatus?: 'free' | 'premium' | 'admin';\n\tsubscription_id?: string;\n\tcreated_at?: string;\n\tupdated_at?: string;\n}\n\nexport interface ITag {\n\tid?: string;\n\tname?: string;\n\tuser_id?: string;\n\tcount?: number;\n}\n"]}
@@ -0,0 +1,172 @@
1
+ "use strict";
2
+ /**
3
+ * Author: marco
4
+ * Last updated: 2025-06-01
5
+ */
6
+ Object.defineProperty(exports, "__esModule", { value: true });
7
+ exports.cleanObject = cleanObject;
8
+ exports.buildQueryString = buildQueryString;
9
+ exports.validateRequiredFields = validateRequiredFields;
10
+ exports.formatDate = formatDate;
11
+ exports.parsePaginationParams = parsePaginationParams;
12
+ exports.buildRequestOptions = buildRequestOptions;
13
+ exports.extractErrorMessage = extractErrorMessage;
14
+ exports.transformContactData = transformContactData;
15
+ exports.transformNoteData = transformNoteData;
16
+ exports.transformJobData = transformJobData;
17
+ /**
18
+ * Utility functions for InNotes N8N node
19
+ */
20
+ /**
21
+ * Clean undefined values from an object
22
+ */
23
+ function cleanObject(obj) {
24
+ const cleaned = {};
25
+ for (const [key, value] of Object.entries(obj)) {
26
+ if (value !== undefined && value !== null && value !== '') {
27
+ cleaned[key] = value;
28
+ }
29
+ }
30
+ return cleaned;
31
+ }
32
+ /**
33
+ * Convert query parameters to URL search params
34
+ */
35
+ function buildQueryString(params) {
36
+ const cleanedParams = cleanObject(params);
37
+ const searchParams = new URLSearchParams();
38
+ for (const [key, value] of Object.entries(cleanedParams)) {
39
+ if (Array.isArray(value)) {
40
+ value.forEach(item => searchParams.append(key, String(item)));
41
+ }
42
+ else {
43
+ searchParams.append(key, String(value));
44
+ }
45
+ }
46
+ return searchParams.toString();
47
+ }
48
+ /**
49
+ * Validate required fields are present
50
+ */
51
+ function validateRequiredFields(data, requiredFields) {
52
+ const missingFields = requiredFields.filter(field => !data[field]);
53
+ if (missingFields.length > 0) {
54
+ throw new Error(`Missing required fields: ${missingFields.join(', ')}`);
55
+ }
56
+ }
57
+ /**
58
+ * Format date for API requests
59
+ */
60
+ function formatDate(date) {
61
+ if (typeof date === 'string') {
62
+ date = new Date(date);
63
+ }
64
+ return date.toISOString();
65
+ }
66
+ /**
67
+ * Parse pagination parameters
68
+ */
69
+ function parsePaginationParams(limit, offset) {
70
+ return {
71
+ limit: limit !== null && limit !== void 0 ? limit : 50,
72
+ offset: offset !== null && offset !== void 0 ? offset : 0,
73
+ };
74
+ }
75
+ /**
76
+ * Build request options for HTTP calls
77
+ */
78
+ function buildRequestOptions(method, url, data, params) {
79
+ const options = {
80
+ method,
81
+ url,
82
+ headers: {
83
+ 'Content-Type': 'application/json',
84
+ },
85
+ };
86
+ if (data) {
87
+ options.body = cleanObject(data);
88
+ }
89
+ if (params) {
90
+ const queryString = buildQueryString(params);
91
+ if (queryString) {
92
+ options.url = `${url}?${queryString}`;
93
+ }
94
+ }
95
+ return options;
96
+ }
97
+ /**
98
+ * Extract error message from API response
99
+ */
100
+ function extractErrorMessage(error) {
101
+ var _a, _b, _c, _d;
102
+ if ((_b = (_a = error.response) === null || _a === void 0 ? void 0 : _a.body) === null || _b === void 0 ? void 0 : _b.message) {
103
+ return error.response.body.message;
104
+ }
105
+ if ((_d = (_c = error.response) === null || _c === void 0 ? void 0 : _c.body) === null || _d === void 0 ? void 0 : _d.error) {
106
+ return error.response.body.error;
107
+ }
108
+ if (error.message) {
109
+ return error.message;
110
+ }
111
+ return 'Unknown error occurred';
112
+ }
113
+ /**
114
+ * Transform InNotes contact data for output
115
+ */
116
+ function transformContactData(contact) {
117
+ var _a, _b;
118
+ return {
119
+ id: contact.id,
120
+ name: contact.name,
121
+ email: contact.email,
122
+ phone: contact.phone,
123
+ linkedinUrl: contact.linkedinUrl,
124
+ company: contact.company,
125
+ position: contact.position,
126
+ location: contact.location,
127
+ tags: (_a = contact.tags) !== null && _a !== void 0 ? _a : [],
128
+ status: contact.status,
129
+ notes: (_b = contact.notes) !== null && _b !== void 0 ? _b : [],
130
+ createdAt: contact.createdAt,
131
+ updatedAt: contact.updatedAt,
132
+ };
133
+ }
134
+ /**
135
+ * Transform InNotes note data for output
136
+ */
137
+ function transformNoteData(note) {
138
+ var _a, _b;
139
+ return {
140
+ id: note.id,
141
+ contactId: note.contactId,
142
+ content: note.content,
143
+ type: note.type,
144
+ tags: (_a = note.tags) !== null && _a !== void 0 ? _a : [],
145
+ attachments: (_b = note.attachments) !== null && _b !== void 0 ? _b : [],
146
+ createdAt: note.createdAt,
147
+ updatedAt: note.updatedAt,
148
+ };
149
+ }
150
+ /**
151
+ * Transform InNotes job data for output
152
+ */
153
+ function transformJobData(job) {
154
+ var _a, _b;
155
+ return {
156
+ id: job.id,
157
+ title: job.title,
158
+ company: job.company,
159
+ description: job.description,
160
+ url: job.url,
161
+ status: job.status,
162
+ salaryRange: job.salaryRange,
163
+ location: job.location,
164
+ type: job.type,
165
+ contacts: (_a = job.contacts) !== null && _a !== void 0 ? _a : [],
166
+ notes: (_b = job.notes) !== null && _b !== void 0 ? _b : [],
167
+ createdAt: job.createdAt,
168
+ updatedAt: job.updatedAt,
169
+ };
170
+ }
171
+
172
+ //# sourceMappingURL=helpers.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../utils/helpers.ts"],"names":[],"mappings":"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","file":"helpers.js","sourcesContent":["/**\n * Author: marco\n * Last updated: 2025-06-01\n */\n\nimport { IDataObject } from 'n8n-workflow';\n\n/**\n * Utility functions for InNotes N8N node\n */\n\n/**\n * Clean undefined values from an object\n */\nexport function cleanObject(obj: IDataObject): IDataObject {\n\tconst cleaned: IDataObject = {};\n\tfor (const [key, value] of Object.entries(obj)) {\n\t\tif (value !== undefined && value !== null && value !== '') {\n\t\t\tcleaned[key] = value;\n\t\t}\n\t}\n\treturn cleaned;\n}\n\n/**\n * Convert query parameters to URL search params\n */\nexport function buildQueryString(params: IDataObject): string {\n\tconst cleanedParams = cleanObject(params);\n\tconst searchParams = new URLSearchParams();\n\n\tfor (const [key, value] of Object.entries(cleanedParams)) {\n\t\tif (Array.isArray(value)) {\n\t\t\tvalue.forEach(item => searchParams.append(key, String(item)));\n\t\t} else {\n\t\t\tsearchParams.append(key, String(value));\n\t\t}\n\t}\n\n\treturn searchParams.toString();\n}\n\n/**\n * Validate required fields are present\n */\nexport function validateRequiredFields(data: IDataObject, requiredFields: string[]): void {\n\tconst missingFields = requiredFields.filter(field => !data[field]);\n\tif (missingFields.length > 0) {\n\t\tthrow new Error(`Missing required fields: ${missingFields.join(', ')}`);\n\t}\n}\n\n/**\n * Format date for API requests\n */\nexport function formatDate(date: Date | string): string {\n\tif (typeof date === 'string') {\n\t\tdate = new Date(date);\n\t}\n\treturn date.toISOString();\n}\n\n/**\n * Parse pagination parameters\n */\nexport function parsePaginationParams(limit?: number, offset?: number) {\n\treturn {\n\t\tlimit: limit ?? 50,\n\t\toffset: offset ?? 0,\n\t};\n}\n\n/**\n * Build request options for HTTP calls\n */\nexport function buildRequestOptions(\n\tmethod: string,\n\turl: string,\n\tdata?: IDataObject,\n\tparams?: IDataObject,\n) {\n\tconst options: IDataObject = {\n\t\tmethod,\n\t\turl,\n\t\theaders: {\n\t\t\t'Content-Type': 'application/json',\n\t\t},\n\t};\n\n\tif (data) {\n\t\toptions.body = cleanObject(data);\n\t}\n\n\tif (params) {\n\t\tconst queryString = buildQueryString(params);\n\t\tif (queryString) {\n\t\t\toptions.url = `${url}?${queryString}`;\n\t\t}\n\t}\n\n\treturn options;\n}\n\n/**\n * Extract error message from API response\n */\nexport function extractErrorMessage(error: any): string {\n\tif (error.response?.body?.message) {\n\t\treturn error.response.body.message;\n\t}\n\tif (error.response?.body?.error) {\n\t\treturn error.response.body.error;\n\t}\n\tif (error.message) {\n\t\treturn error.message;\n\t}\n\treturn 'Unknown error occurred';\n}\n\n/**\n * Transform InNotes contact data for output\n */\nexport function transformContactData(contact: IDataObject): IDataObject {\n\treturn {\n\t\tid: contact.id,\n\t\tname: contact.name,\n\t\temail: contact.email,\n\t\tphone: contact.phone,\n\t\tlinkedinUrl: contact.linkedinUrl,\n\t\tcompany: contact.company,\n\t\tposition: contact.position,\n\t\tlocation: contact.location,\n\t\ttags: contact.tags ?? [],\n\t\tstatus: contact.status,\n\t\tnotes: contact.notes ?? [],\n\t\tcreatedAt: contact.createdAt,\n\t\tupdatedAt: contact.updatedAt,\n\t};\n}\n\n/**\n * Transform InNotes note data for output\n */\nexport function transformNoteData(note: IDataObject): IDataObject {\n\treturn {\n\t\tid: note.id,\n\t\tcontactId: note.contactId,\n\t\tcontent: note.content,\n\t\ttype: note.type,\n\t\ttags: note.tags ?? [],\n\t\tattachments: note.attachments ?? [],\n\t\tcreatedAt: note.createdAt,\n\t\tupdatedAt: note.updatedAt,\n\t};\n}\n\n/**\n * Transform InNotes job data for output\n */\nexport function transformJobData(job: IDataObject): IDataObject {\n\treturn {\n\t\tid: job.id,\n\t\ttitle: job.title,\n\t\tcompany: job.company,\n\t\tdescription: job.description,\n\t\turl: job.url,\n\t\tstatus: job.status,\n\t\tsalaryRange: job.salaryRange,\n\t\tlocation: job.location,\n\t\ttype: job.type,\n\t\tcontacts: job.contacts ?? [],\n\t\tnotes: job.notes ?? [],\n\t\tcreatedAt: job.createdAt,\n\t\tupdatedAt: job.updatedAt,\n\t};\n}\n"]}