diff --git a/packages/nodes-base/credentials/NocoDbApiToken.credentials.ts b/packages/nodes-base/credentials/NocoDbApiToken.credentials.ts index a545f121c2..45ad53bcab 100644 --- a/packages/nodes-base/credentials/NocoDbApiToken.credentials.ts +++ b/packages/nodes-base/credentials/NocoDbApiToken.credentials.ts @@ -1,4 +1,9 @@ -import type { IAuthenticateGeneric, ICredentialType, INodeProperties } from 'n8n-workflow'; +import type { + IAuthenticateGeneric, + ICredentialTestRequest, + ICredentialType, + INodeProperties, +} from 'n8n-workflow'; export class NocoDbApiToken implements ICredentialType { name = 'nocoDbApiToken'; @@ -31,4 +36,11 @@ export class NocoDbApiToken implements ICredentialType { }, }, }; + + test: ICredentialTestRequest = { + request: { + baseURL: '={{ $credentials.host }}', + url: '/api/v1/auth/user/me', + }, + }; } diff --git a/packages/nodes-base/nodes/NocoDB/NocoDB.node.ts b/packages/nodes-base/nodes/NocoDB/NocoDB.node.ts index 71e139a92c..85dca04833 100644 --- a/packages/nodes-base/nodes/NocoDB/NocoDB.node.ts +++ b/packages/nodes-base/nodes/NocoDB/NocoDB.node.ts @@ -328,17 +328,24 @@ export class NocoDB implements INodeType { if (operation === 'delete') { requestMethod = 'DELETE'; + let primaryKey = 'id'; + if (version === 1) { endPoint = `/nc/${projectId}/api/v1/${table}/bulk`; } else if (version === 2) { endPoint = `/api/v1/db/data/bulk/noco/${projectId}/${table}`; + + primaryKey = this.getNodeParameter('primaryKey', 0) as string; + if (primaryKey === 'custom') { + primaryKey = this.getNodeParameter('customPrimaryKey', 0) as string; + } } const body: IDataObject[] = []; for (let i = 0; i < items.length; i++) { const id = this.getNodeParameter('id', i) as string; - body.push({ id }); + body.push({ [primaryKey]: id }); } try { @@ -532,18 +539,25 @@ export class NocoDB implements INodeType { if (operation === 'update') { requestMethod = 'PATCH'; + let primaryKey = 'id'; if (version === 1) { endPoint = `/nc/${projectId}/api/v1/${table}/bulk`; requestMethod = 'PUT'; } else if (version === 2) { endPoint = `/api/v1/db/data/bulk/noco/${projectId}/${table}`; + + primaryKey = this.getNodeParameter('primaryKey', 0) as string; + if (primaryKey === 'custom') { + primaryKey = this.getNodeParameter('customPrimaryKey', 0) as string; + } } + const body: IDataObject[] = []; for (let i = 0; i < items.length; i++) { const id = this.getNodeParameter('id', i) as string; - const newItem: IDataObject = { id }; + const newItem: IDataObject = { [primaryKey]: id }; const dataToSend = this.getNodeParameter('dataToSend', i) as | 'defineBelow' | 'autoMapInputData'; diff --git a/packages/nodes-base/nodes/NocoDB/OperationDescription.ts b/packages/nodes-base/nodes/NocoDB/OperationDescription.ts index a5e269a13a..be2be114ed 100644 --- a/packages/nodes-base/nodes/NocoDB/OperationDescription.ts +++ b/packages/nodes-base/nodes/NocoDB/OperationDescription.ts @@ -65,22 +65,65 @@ export const operationFields: INodeProperties[] = [ required: true, description: 'The name of the table', }, + { + displayName: 'Primary Key Type', + name: 'primaryKey', + type: 'options', + default: 'id', + options: [ + { + name: 'Default', + value: 'id', + description: + 'Default, added when table was created from UI by those options: Create new table / Import from Excel / Import from CSV', + }, + { + name: 'Imported From Airtable', + value: 'ncRecordId', + description: 'Select if table was imported from Airtable', + }, + { + name: 'Custom', + value: 'custom', + description: + 'When connecting to existing external database as existing primary key field is retained as is, enter the name of the primary key field below', + }, + ], + displayOptions: { + show: { + operation: ['delete', 'update'], + }, + }, + }, + { + displayName: 'Field Name', + name: 'customPrimaryKey', + type: 'string', + default: '', + displayOptions: { + show: { + operation: ['delete', 'update'], + primaryKey: ['custom'], + }, + }, + }, + { + displayName: 'Row ID Value', + name: 'id', + type: 'string', + default: '', + required: true, + description: 'The value of the ID field', + displayOptions: { + show: { + operation: ['delete', 'get', 'update'], + }, + }, + }, // ---------------------------------- // delete // ---------------------------------- - { - displayName: 'Row ID', - name: 'id', - type: 'string', - displayOptions: { - show: { - operation: ['delete'], - }, - }, - default: '', - required: true, - description: 'ID of the row to delete', - }, + // ---------------------------------- // getAll // ---------------------------------- @@ -222,19 +265,6 @@ export const operationFields: INodeProperties[] = [ // ---------------------------------- // get // ---------------------------------- - { - displayName: 'Row ID', - name: 'id', - type: 'string', - displayOptions: { - show: { - operation: ['get'], - }, - }, - default: '', - required: true, - description: 'ID of the row to return', - }, { displayName: 'Download Attachments', name: 'downloadAttachments', @@ -265,19 +295,6 @@ export const operationFields: INodeProperties[] = [ // ---------------------------------- // update // ---------------------------------- - { - displayName: 'Row ID', - name: 'id', - type: 'string', - displayOptions: { - show: { - operation: ['update'], - }, - }, - default: '', - required: true, - description: 'ID of the row to update', - }, // ---------------------------------- // Shared // ----------------------------------