mirror of
https://github.com/Abdulazizzn/n8n-enterprise-unlocked.git
synced 2025-12-17 01:56:46 +00:00
feat(NocoDB Node): Add new data apis and workspace support (#7329)
- Changed old NocoDB logo with new one To support new release of [NocoDB (v0.202.4)](https://github.com/nocodb/nocodb/releases/tag/0.202.4): - Added a new version(3) to support new data apis and workspaces - Renamed `project` to `base` for new version (kept labels for old versions for backwards compatibility) --------- Signed-off-by: mertmit <mertmit99@gmail.com> Co-authored-by: Jonathan Bennetts <jonathan.bennetts@gmail.com>
This commit is contained in:
@@ -20,7 +20,7 @@ export class NocoDB implements INodeType {
|
||||
name: 'nocoDb',
|
||||
icon: 'file:nocodb.svg',
|
||||
group: ['input'],
|
||||
version: [1, 2],
|
||||
version: [1, 2, 3],
|
||||
subtitle: '={{$parameter["operation"] + ": " + $parameter["resource"]}}',
|
||||
description: 'Read, update, write and delete data from NocoDB',
|
||||
defaults: {
|
||||
@@ -54,14 +54,14 @@ export class NocoDB implements INodeType {
|
||||
name: 'authentication',
|
||||
type: 'options',
|
||||
options: [
|
||||
{
|
||||
name: 'User Token',
|
||||
value: 'nocoDb',
|
||||
},
|
||||
{
|
||||
name: 'API Token',
|
||||
value: 'nocoDbApiToken',
|
||||
},
|
||||
{
|
||||
name: 'User Token',
|
||||
value: 'nocoDb',
|
||||
},
|
||||
],
|
||||
default: 'nocoDb',
|
||||
},
|
||||
@@ -69,11 +69,6 @@ export class NocoDB implements INodeType {
|
||||
displayName: 'API Version',
|
||||
name: 'version',
|
||||
type: 'options',
|
||||
displayOptions: {
|
||||
show: {
|
||||
'@version': [1],
|
||||
},
|
||||
},
|
||||
isNodeSetting: true,
|
||||
options: [
|
||||
{
|
||||
@@ -84,18 +79,22 @@ export class NocoDB implements INodeType {
|
||||
name: 'v0.90.0 Onwards',
|
||||
value: 2,
|
||||
},
|
||||
{
|
||||
name: 'v0.200.0 Onwards',
|
||||
value: 3,
|
||||
},
|
||||
],
|
||||
displayOptions: {
|
||||
show: {
|
||||
'@version': [1],
|
||||
},
|
||||
},
|
||||
default: 1,
|
||||
},
|
||||
{
|
||||
displayName: 'API Version',
|
||||
name: 'version',
|
||||
type: 'options',
|
||||
displayOptions: {
|
||||
show: {
|
||||
'@version': [2],
|
||||
},
|
||||
},
|
||||
isNodeSetting: true,
|
||||
options: [
|
||||
{
|
||||
@@ -106,9 +105,44 @@ export class NocoDB implements INodeType {
|
||||
name: 'v0.90.0 Onwards',
|
||||
value: 2,
|
||||
},
|
||||
{
|
||||
name: 'v0.200.0 Onwards',
|
||||
value: 3,
|
||||
},
|
||||
],
|
||||
displayOptions: {
|
||||
show: {
|
||||
'@version': [2],
|
||||
},
|
||||
},
|
||||
default: 2,
|
||||
},
|
||||
{
|
||||
displayName: 'API Version',
|
||||
name: 'version',
|
||||
type: 'options',
|
||||
isNodeSetting: true,
|
||||
options: [
|
||||
{
|
||||
name: 'Before v0.90.0',
|
||||
value: 1,
|
||||
},
|
||||
{
|
||||
name: 'v0.90.0 Onwards',
|
||||
value: 2,
|
||||
},
|
||||
{
|
||||
name: 'v0.200.0 Onwards',
|
||||
value: 3,
|
||||
},
|
||||
],
|
||||
displayOptions: {
|
||||
show: {
|
||||
'@version': [3],
|
||||
},
|
||||
},
|
||||
default: 3,
|
||||
},
|
||||
{
|
||||
displayName: 'Resource',
|
||||
name: 'resource',
|
||||
@@ -172,26 +206,51 @@ export class NocoDB implements INodeType {
|
||||
|
||||
methods = {
|
||||
loadOptions: {
|
||||
async getProjects(this: ILoadOptionsFunctions) {
|
||||
async getWorkspaces(this: ILoadOptionsFunctions) {
|
||||
try {
|
||||
const requestMethod = 'GET';
|
||||
const endpoint = '/api/v1/db/meta/projects/';
|
||||
const endpoint = '/api/v1/workspaces/';
|
||||
const responseData = await apiRequest.call(this, requestMethod, endpoint, {}, {});
|
||||
return responseData.list.map((i: IDataObject) => ({ name: i.title, value: i.id }));
|
||||
} catch (e) {
|
||||
return [{ name: 'No Workspace', value: 'none' }];
|
||||
}
|
||||
},
|
||||
async getBases(this: ILoadOptionsFunctions) {
|
||||
const version = this.getNodeParameter('version', 0) as number;
|
||||
const workspaceId = this.getNodeParameter('workspaceId', 0) as string;
|
||||
try {
|
||||
if (workspaceId && workspaceId !== 'none') {
|
||||
const requestMethod = 'GET';
|
||||
const endpoint = `/api/v1/workspaces/${workspaceId}/bases/`;
|
||||
const responseData = await apiRequest.call(this, requestMethod, endpoint, {}, {});
|
||||
return responseData.list.map((i: IDataObject) => ({ name: i.title, value: i.id }));
|
||||
} else {
|
||||
const requestMethod = 'GET';
|
||||
const endpoint = version === 3 ? '/api/v2/meta/bases/' : '/api/v1/db/meta/projects/';
|
||||
const responseData = await apiRequest.call(this, requestMethod, endpoint, {}, {});
|
||||
return responseData.list.map((i: IDataObject) => ({ name: i.title, value: i.id }));
|
||||
}
|
||||
} catch (e) {
|
||||
throw new NodeOperationError(
|
||||
this.getNode(),
|
||||
new Error('Error while fetching projects!', { cause: e }),
|
||||
new Error(`Error while fetching ${version === 3 ? 'bases' : 'projects'}!`, {
|
||||
cause: e,
|
||||
}),
|
||||
);
|
||||
}
|
||||
},
|
||||
// This only supports using the Project ID
|
||||
// This only supports using the Base ID
|
||||
async getTables(this: ILoadOptionsFunctions) {
|
||||
const projectId = this.getNodeParameter('projectId', 0) as string;
|
||||
if (projectId) {
|
||||
const version = this.getNodeParameter('version', 0) as number;
|
||||
const baseId = this.getNodeParameter('projectId', 0) as string;
|
||||
if (baseId) {
|
||||
try {
|
||||
const requestMethod = 'GET';
|
||||
const endpoint = `/api/v1/db/meta/projects/${projectId}/tables`;
|
||||
const endpoint =
|
||||
version === 3
|
||||
? `/api/v2/meta/bases/${baseId}/tables`
|
||||
: `/api/v1/db/meta/projects/${baseId}/tables`;
|
||||
const responseData = await apiRequest.call(this, requestMethod, endpoint, {}, {});
|
||||
return responseData.list.map((i: IDataObject) => ({ name: i.title, value: i.id }));
|
||||
} catch (e) {
|
||||
@@ -201,7 +260,10 @@ export class NocoDB implements INodeType {
|
||||
);
|
||||
}
|
||||
} else {
|
||||
throw new NodeOperationError(this.getNode(), 'No project selected!');
|
||||
throw new NodeOperationError(
|
||||
this.getNode(),
|
||||
`No ${version === 3 ? 'base' : 'project'} selected!`,
|
||||
);
|
||||
}
|
||||
},
|
||||
},
|
||||
@@ -223,7 +285,7 @@ export class NocoDB implements INodeType {
|
||||
|
||||
let endPoint = '';
|
||||
|
||||
const projectId = this.getNodeParameter('projectId', 0) as string;
|
||||
const baseId = this.getNodeParameter('projectId', 0) as string;
|
||||
const table = this.getNodeParameter('table', 0) as string;
|
||||
|
||||
if (resource === 'row') {
|
||||
@@ -231,9 +293,11 @@ export class NocoDB implements INodeType {
|
||||
requestMethod = 'POST';
|
||||
|
||||
if (version === 1) {
|
||||
endPoint = `/nc/${projectId}/api/v1/${table}/bulk`;
|
||||
endPoint = `/nc/${baseId}/api/v1/${table}/bulk`;
|
||||
} else if (version === 2) {
|
||||
endPoint = `/api/v1/db/data/bulk/noco/${projectId}/${table}`;
|
||||
endPoint = `/api/v1/db/data/bulk/noco/${baseId}/${table}`;
|
||||
} else if (version === 3) {
|
||||
endPoint = `/api/v2/tables/${table}/records`;
|
||||
}
|
||||
|
||||
const body: IDataObject[] = [];
|
||||
@@ -278,7 +342,7 @@ export class NocoDB implements INodeType {
|
||||
},
|
||||
json: JSON.stringify({
|
||||
api: 'xcAttachmentUpload',
|
||||
project_id: projectId,
|
||||
project_id: baseId,
|
||||
dbAlias: 'db',
|
||||
args: {},
|
||||
}),
|
||||
@@ -289,6 +353,8 @@ export class NocoDB implements INodeType {
|
||||
postUrl = '/dashboard';
|
||||
} else if (version === 2) {
|
||||
postUrl = '/api/v1/db/storage/upload';
|
||||
} else if (version === 3) {
|
||||
postUrl = '/api/v2/storage/upload';
|
||||
}
|
||||
|
||||
responseData = await apiRequest.call(
|
||||
@@ -296,13 +362,15 @@ export class NocoDB implements INodeType {
|
||||
'POST',
|
||||
postUrl,
|
||||
{},
|
||||
{ project_id: projectId },
|
||||
version === 3 ? { base_id: baseId } : { project_id: baseId },
|
||||
undefined,
|
||||
{
|
||||
formData,
|
||||
},
|
||||
);
|
||||
newItem[field.fieldName] = JSON.stringify([responseData]);
|
||||
newItem[field.fieldName] = JSON.stringify(
|
||||
Array.isArray(responseData) ? responseData : [responseData],
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -311,13 +379,21 @@ export class NocoDB implements INodeType {
|
||||
try {
|
||||
responseData = await apiRequest.call(this, requestMethod, endPoint, body, qs);
|
||||
|
||||
// Calculate ID manually and add to return data
|
||||
let id = responseData[0];
|
||||
for (let i = body.length - 1; i >= 0; i--) {
|
||||
body[i].id = id--;
|
||||
}
|
||||
if (version === 3) {
|
||||
for (let i = body.length - 1; i >= 0; i--) {
|
||||
body[i] = { ...body[i], ...responseData[i] };
|
||||
}
|
||||
|
||||
returnData.push(...body);
|
||||
returnData.push(...body);
|
||||
} else {
|
||||
// Calculate ID manually and add to return data
|
||||
let id = responseData[0];
|
||||
for (let i = body.length - 1; i >= 0; i--) {
|
||||
body[i].id = id--;
|
||||
}
|
||||
|
||||
returnData.push(...body);
|
||||
}
|
||||
} catch (error) {
|
||||
if (this.continueOnFail()) {
|
||||
returnData.push({ error: error.toString() });
|
||||
@@ -331,9 +407,16 @@ export class NocoDB implements INodeType {
|
||||
let primaryKey = 'id';
|
||||
|
||||
if (version === 1) {
|
||||
endPoint = `/nc/${projectId}/api/v1/${table}/bulk`;
|
||||
endPoint = `/nc/${baseId}/api/v1/${table}/bulk`;
|
||||
} else if (version === 2) {
|
||||
endPoint = `/api/v1/db/data/bulk/noco/${projectId}/${table}`;
|
||||
endPoint = `/api/v1/db/data/bulk/noco/${baseId}/${table}`;
|
||||
|
||||
primaryKey = this.getNodeParameter('primaryKey', 0) as string;
|
||||
if (primaryKey === 'custom') {
|
||||
primaryKey = this.getNodeParameter('customPrimaryKey', 0) as string;
|
||||
}
|
||||
} else if (version === 3) {
|
||||
endPoint = `/api/v2/tables/${table}/records`;
|
||||
|
||||
primaryKey = this.getNodeParameter('primaryKey', 0) as string;
|
||||
if (primaryKey === 'custom') {
|
||||
@@ -349,13 +432,7 @@ export class NocoDB implements INodeType {
|
||||
}
|
||||
|
||||
try {
|
||||
responseData = (await apiRequest.call(
|
||||
this,
|
||||
requestMethod,
|
||||
endPoint,
|
||||
body,
|
||||
qs,
|
||||
)) as number[];
|
||||
responseData = (await apiRequest.call(this, requestMethod, endPoint, body, qs)) as any[];
|
||||
if (version === 1) {
|
||||
returnData.push(...items.map((item) => item.json));
|
||||
} else if (version === 2) {
|
||||
@@ -377,6 +454,8 @@ export class NocoDB implements INodeType {
|
||||
};
|
||||
}),
|
||||
);
|
||||
} else if (version === 3) {
|
||||
returnData.push(...responseData);
|
||||
}
|
||||
} catch (error) {
|
||||
if (this.continueOnFail()) {
|
||||
@@ -394,9 +473,11 @@ export class NocoDB implements INodeType {
|
||||
requestMethod = 'GET';
|
||||
|
||||
if (version === 1) {
|
||||
endPoint = `/nc/${projectId}/api/v1/${table}`;
|
||||
endPoint = `/nc/${baseId}/api/v1/${table}`;
|
||||
} else if (version === 2) {
|
||||
endPoint = `/api/v1/db/data/noco/${projectId}/${table}`;
|
||||
endPoint = `/api/v1/db/data/noco/${baseId}/${table}`;
|
||||
} else if (version === 3) {
|
||||
endPoint = `/api/v2/tables/${table}/records`;
|
||||
}
|
||||
|
||||
returnAll = this.getNodeParameter('returnAll', 0);
|
||||
@@ -421,7 +502,7 @@ export class NocoDB implements INodeType {
|
||||
} else {
|
||||
qs.limit = this.getNodeParameter('limit', 0);
|
||||
responseData = await apiRequest.call(this, requestMethod, endPoint, {}, qs);
|
||||
if (version === 2) {
|
||||
if (version === 2 || version === 3) {
|
||||
responseData = responseData.list;
|
||||
}
|
||||
}
|
||||
@@ -468,9 +549,11 @@ export class NocoDB implements INodeType {
|
||||
const id = this.getNodeParameter('id', i) as string;
|
||||
|
||||
if (version === 1) {
|
||||
endPoint = `/nc/${projectId}/api/v1/${table}/${id}`;
|
||||
endPoint = `/nc/${baseId}/api/v1/${table}/${id}`;
|
||||
} else if (version === 2) {
|
||||
endPoint = `/api/v1/db/data/noco/${projectId}/${table}/${id}`;
|
||||
endPoint = `/api/v1/db/data/noco/${baseId}/${table}/${id}`;
|
||||
} else if (version === 3) {
|
||||
endPoint = `/api/v2/tables/${table}/records/${id}`;
|
||||
}
|
||||
|
||||
responseData = await apiRequest.call(this, requestMethod, endPoint, {}, qs);
|
||||
@@ -542,22 +625,24 @@ export class NocoDB implements INodeType {
|
||||
let primaryKey = 'id';
|
||||
|
||||
if (version === 1) {
|
||||
endPoint = `/nc/${projectId}/api/v1/${table}/bulk`;
|
||||
endPoint = `/nc/${baseId}/api/v1/${table}/bulk`;
|
||||
requestMethod = 'PUT';
|
||||
} else if (version === 2) {
|
||||
endPoint = `/api/v1/db/data/bulk/noco/${projectId}/${table}`;
|
||||
endPoint = `/api/v1/db/data/bulk/noco/${baseId}/${table}`;
|
||||
|
||||
primaryKey = this.getNodeParameter('primaryKey', 0) as string;
|
||||
if (primaryKey === 'custom') {
|
||||
primaryKey = this.getNodeParameter('customPrimaryKey', 0) as string;
|
||||
}
|
||||
} else if (version === 3) {
|
||||
endPoint = `/api/v2/tables/${table}/records`;
|
||||
}
|
||||
|
||||
const body: IDataObject[] = [];
|
||||
|
||||
for (let i = 0; i < items.length; i++) {
|
||||
const id = this.getNodeParameter('id', i) as string;
|
||||
const newItem: IDataObject = { [primaryKey]: id };
|
||||
const id = version === 3 ? null : (this.getNodeParameter('id', i) as string);
|
||||
const newItem: IDataObject = version === 3 ? {} : { [primaryKey]: id };
|
||||
const dataToSend = this.getNodeParameter('dataToSend', i) as
|
||||
| 'defineBelow'
|
||||
| 'autoMapInputData';
|
||||
@@ -596,7 +681,7 @@ export class NocoDB implements INodeType {
|
||||
},
|
||||
json: JSON.stringify({
|
||||
api: 'xcAttachmentUpload',
|
||||
project_id: projectId,
|
||||
project_id: baseId,
|
||||
dbAlias: 'db',
|
||||
args: {},
|
||||
}),
|
||||
@@ -606,19 +691,24 @@ export class NocoDB implements INodeType {
|
||||
postUrl = '/dashboard';
|
||||
} else if (version === 2) {
|
||||
postUrl = '/api/v1/db/storage/upload';
|
||||
} else if (version === 3) {
|
||||
postUrl = '/api/v2/storage/upload';
|
||||
}
|
||||
|
||||
responseData = await apiRequest.call(
|
||||
this,
|
||||
'POST',
|
||||
postUrl,
|
||||
{},
|
||||
{ project_id: projectId },
|
||||
version === 3 ? { base_id: baseId } : { project_id: baseId },
|
||||
undefined,
|
||||
{
|
||||
formData,
|
||||
},
|
||||
);
|
||||
newItem[field.fieldName] = JSON.stringify([responseData]);
|
||||
newItem[field.fieldName] = JSON.stringify(
|
||||
Array.isArray(responseData) ? responseData : [responseData],
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -626,13 +716,7 @@ export class NocoDB implements INodeType {
|
||||
}
|
||||
|
||||
try {
|
||||
responseData = (await apiRequest.call(
|
||||
this,
|
||||
requestMethod,
|
||||
endPoint,
|
||||
body,
|
||||
qs,
|
||||
)) as number[];
|
||||
responseData = (await apiRequest.call(this, requestMethod, endPoint, body, qs)) as any[];
|
||||
|
||||
if (version === 1) {
|
||||
returnData.push(...body);
|
||||
@@ -655,6 +739,12 @@ export class NocoDB implements INodeType {
|
||||
};
|
||||
}),
|
||||
);
|
||||
} else if (version === 3) {
|
||||
for (let i = body.length - 1; i >= 0; i--) {
|
||||
body[i] = { ...body[i], ...responseData[i] };
|
||||
}
|
||||
|
||||
returnData.push(...body);
|
||||
}
|
||||
} catch (error) {
|
||||
if (this.continueOnFail()) {
|
||||
|
||||
Reference in New Issue
Block a user