From 7f2fe2504874f55f74f3b6d9336543d8d2fe7e49 Mon Sep 17 00:00:00 2001 From: Ricardo Espinoza Date: Fri, 13 Dec 2019 16:50:59 -0500 Subject: [PATCH 1/3] done --- .../credentials/CodaApi.credentials.ts | 23 ++ packages/nodes-base/nodes/Coda/Coda.node.ts | 299 ++++++++++++++++++ .../nodes-base/nodes/Coda/GenericFunctions.ts | 66 ++++ .../nodes-base/nodes/Coda/RowDescription.ts | 95 ++++++ packages/nodes-base/nodes/Coda/coda.png | Bin 0 -> 1893 bytes packages/nodes-base/package.json | 2 + 6 files changed, 485 insertions(+) create mode 100644 packages/nodes-base/credentials/CodaApi.credentials.ts create mode 100644 packages/nodes-base/nodes/Coda/Coda.node.ts create mode 100644 packages/nodes-base/nodes/Coda/GenericFunctions.ts create mode 100644 packages/nodes-base/nodes/Coda/RowDescription.ts create mode 100644 packages/nodes-base/nodes/Coda/coda.png diff --git a/packages/nodes-base/credentials/CodaApi.credentials.ts b/packages/nodes-base/credentials/CodaApi.credentials.ts new file mode 100644 index 0000000000..c7e8befe4c --- /dev/null +++ b/packages/nodes-base/credentials/CodaApi.credentials.ts @@ -0,0 +1,23 @@ +import { + ICredentialType, + NodePropertyTypes, +} from 'n8n-workflow'; + +export class CodaApi implements ICredentialType { + name = 'codaApi'; + displayName = 'Coda API'; + properties = [ + { + displayName: 'Doc ID', + name: 'docId', + type: 'string' as NodePropertyTypes, + default: '', + }, + { + displayName: 'Access Token', + name: 'accessToken', + type: 'string' as NodePropertyTypes, + default: '', + }, + ]; +} diff --git a/packages/nodes-base/nodes/Coda/Coda.node.ts b/packages/nodes-base/nodes/Coda/Coda.node.ts new file mode 100644 index 0000000000..605db290f6 --- /dev/null +++ b/packages/nodes-base/nodes/Coda/Coda.node.ts @@ -0,0 +1,299 @@ +import { + IExecuteFunctions, +} from 'n8n-core'; +import { + IDataObject, + INodeTypeDescription, + INodeExecutionData, + INodeType, + ILoadOptionsFunctions, + INodePropertyOptions, +} from 'n8n-workflow'; +import { + codaApiRequest, + codaApiRequestAllItems, +} from './GenericFunctions'; +import { + rowOpeations, + rowFields +} from './RowDescription'; + +export class Coda implements INodeType { + description: INodeTypeDescription = { + displayName: 'Coda', + name: 'Coda', + icon: 'file:coda.png', + group: ['output'], + version: 1, + subtitle: '={{$parameter["operation"] + ": " + $parameter["resource"]}}', + description: 'Consume Coda Beta API', + defaults: { + name: 'Coda', + color: '#c02428', + }, + inputs: ['main'], + outputs: ['main'], + credentials: [ + { + name: 'codaApi', + required: true, + } + ], + properties: [ + { + displayName: 'Resource', + name: 'resource', + type: 'options', + options: [ + { + name: 'Rows', + value: 'row', + description: `You'll likely use this part of the API the most. + These endpoints let you retrieve row data from tables in Coda as well + as create, upsert, update, and delete them.`, + }, + ], + default: 'row', + description: 'Resource to consume.', + }, + ...rowOpeations, + ...rowFields, + ], + }; + + methods = { + loadOptions: { + // Get all the available tables to display them to user so that he can + // select them easily + async getTables(this: ILoadOptionsFunctions): Promise { + const returnData: INodePropertyOptions[] = []; + const credentials = this.getCredentials('codaApi'); + const qs = {}; + let tables; + try { + tables = await codaApiRequestAllItems.call(this,'items', 'GET', `/docs/${credentials!.docId}/tables`, {}, qs); + } catch (err) { + throw new Error(`Coda Error: ${err}`); + } + for (const table of tables) { + const tableName = table.name; + const tableId = table.id; + returnData.push({ + name: tableName, + value: tableId, + }); + } + return returnData; + }, + }, + }; + + async execute(this: IExecuteFunctions): Promise { + const items = this.getInputData(); + const returnData: IDataObject[] = []; + const length = items.length as unknown as number; + let responseData; + const qs: IDataObject = {}; + const resource = this.getNodeParameter('resource', 0) as string; + const operation = this.getNodeParameter('operation', 0) as string; + + for (let i = 0; i < length; i++) { + // if (resource === 'task') { + // //https://developer.getflow.com/api/#tasks_create-task + // if (operation === 'create') { + // const workspaceId = this.getNodeParameter('workspaceId', i) as string; + // const name = this.getNodeParameter('name', i) as string; + // const additionalFields = this.getNodeParameter('additionalFields', i) as IDataObject; + // const body: ITask = { + // organization_id: credentials.organizationId as number, + // }; + // const task: TaskInfo = { + // name, + // workspace_id: parseInt(workspaceId, 10) + // }; + // if (additionalFields.ownerId) { + // task.owner_id = parseInt(additionalFields.ownerId as string, 10); + // } + // if (additionalFields.listId) { + // task.list_id = parseInt(additionalFields.listId as string, 10); + // } + // if (additionalFields.startsOn) { + // task.starts_on = additionalFields.startsOn as string; + // } + // if (additionalFields.dueOn) { + // task.due_on = additionalFields.dueOn as string; + // } + // if (additionalFields.mirrorParentSubscribers) { + // task.mirror_parent_subscribers = additionalFields.mirrorParentSubscribers as boolean; + // } + // if (additionalFields.mirrorParentTags) { + // task.mirror_parent_tags = additionalFields.mirrorParentTags as boolean; + // } + // if (additionalFields.noteContent) { + // task.note_content = additionalFields.noteContent as string; + // } + // if (additionalFields.noteMimeType) { + // task.note_mime_type = additionalFields.noteMimeType as string; + // } + // if (additionalFields.parentId) { + // task.parent_id = parseInt(additionalFields.parentId as string, 10); + // } + // if (additionalFields.positionList) { + // task.position_list = additionalFields.positionList as number; + // } + // if (additionalFields.positionUpcoming) { + // task.position_upcoming = additionalFields.positionUpcoming as number; + // } + // if (additionalFields.position) { + // task.position = additionalFields.position as number; + // } + // if (additionalFields.sectionId) { + // task.section_id = additionalFields.sectionId as number; + // } + // if (additionalFields.tags) { + // task.tags = (additionalFields.tags as string).split(','); + // } + // body.task = task; + // try { + // responseData = await flowApiRequest.call(this, 'POST', '/tasks', body); + // responseData = responseData.task; + // } catch (err) { + // throw new Error(`Flow Error: ${err.message}`); + // } + // } + // //https://developer.getflow.com/api/#tasks_update-a-task + // if (operation === 'update') { + // const workspaceId = this.getNodeParameter('workspaceId', i) as string; + // const taskId = this.getNodeParameter('taskId', i) as string; + // const updateFields = this.getNodeParameter('updateFields', i) as IDataObject; + // const body: ITask = { + // organization_id: credentials.organizationId as number, + // }; + // const task: TaskInfo = { + // workspace_id: parseInt(workspaceId, 10), + // id: parseInt(taskId, 10), + // }; + // if (updateFields.name) { + // task.name = updateFields.name as string; + // } + // if (updateFields.ownerId) { + // task.owner_id = parseInt(updateFields.ownerId as string, 10); + // } + // if (updateFields.listId) { + // task.list_id = parseInt(updateFields.listId as string, 10); + // } + // if (updateFields.startsOn) { + // task.starts_on = updateFields.startsOn as string; + // } + // if (updateFields.dueOn) { + // task.due_on = updateFields.dueOn as string; + // } + // if (updateFields.mirrorParentSubscribers) { + // task.mirror_parent_subscribers = updateFields.mirrorParentSubscribers as boolean; + // } + // if (updateFields.mirrorParentTags) { + // task.mirror_parent_tags = updateFields.mirrorParentTags as boolean; + // } + // if (updateFields.noteContent) { + // task.note_content = updateFields.noteContent as string; + // } + // if (updateFields.noteMimeType) { + // task.note_mime_type = updateFields.noteMimeType as string; + // } + // if (updateFields.parentId) { + // task.parent_id = parseInt(updateFields.parentId as string, 10); + // } + // if (updateFields.positionList) { + // task.position_list = updateFields.positionList as number; + // } + // if (updateFields.positionUpcoming) { + // task.position_upcoming = updateFields.positionUpcoming as number; + // } + // if (updateFields.position) { + // task.position = updateFields.position as number; + // } + // if (updateFields.sectionId) { + // task.section_id = updateFields.sectionId as number; + // } + // if (updateFields.tags) { + // task.tags = (updateFields.tags as string).split(','); + // } + // if (updateFields.completed) { + // task.completed = updateFields.completed as boolean; + // } + // body.task = task; + // try { + // responseData = await flowApiRequest.call(this, 'PUT', `/tasks/${taskId}`, body); + // responseData = responseData.task; + // } catch (err) { + // throw new Error(`Flow Error: ${err.message}`); + // } + // } + // //https://developer.getflow.com/api/#tasks_get-task + // if (operation === 'get') { + // const taskId = this.getNodeParameter('taskId', i) as string; + // const filters = this.getNodeParameter('filters', i) as IDataObject; + // qs.organization_id = credentials.organizationId as number; + // if (filters.include) { + // qs.include = (filters.include as string[]).join(','); + // } + // try { + // responseData = await flowApiRequest.call(this,'GET', `/tasks/${taskId}`, {}, qs); + // } catch (err) { + // throw new Error(`Flow Error: ${err.message}`); + // } + // } + // //https://developer.getflow.com/api/#tasks_get-tasks + // if (operation === 'getAll') { + // const returnAll = this.getNodeParameter('returnAll', i) as boolean; + // const filters = this.getNodeParameter('filters', i) as IDataObject; + // qs.organization_id = credentials.organizationId as number; + // if (filters.include) { + // qs.include = (filters.include as string[]).join(','); + // } + // if (filters.order) { + // qs.order = filters.order as string; + // } + // if (filters.workspaceId) { + // qs.workspace_id = filters.workspaceId as string; + // } + // if (filters.createdBefore) { + // qs.created_before = filters.createdBefore as string; + // } + // if (filters.createdAfter) { + // qs.created_after = filters.createdAfter as string; + // } + // if (filters.updateBefore) { + // qs.updated_before = filters.updateBefore as string; + // } + // if (filters.updateAfter) { + // qs.updated_after = filters.updateAfter as string; + // } + // if (filters.deleted) { + // qs.deleted = filters.deleted as boolean; + // } + // if (filters.cleared) { + // qs.cleared = filters.cleared as boolean; + // } + // try { + // if (returnAll === true) { + // responseData = await FlowApiRequestAllItems.call(this, 'tasks', 'GET', '/tasks', {}, qs); + // } else { + // qs.limit = this.getNodeParameter('limit', i) as number; + // responseData = await flowApiRequest.call(this, 'GET', '/tasks', {}, qs); + // responseData = responseData.tasks; + // } + // } catch (err) { + // throw new Error(`Flow Error: ${err.message}`); + // } + // } + // } + // if (Array.isArray(responseData)) { + // returnData.push.apply(returnData, responseData as IDataObject[]); + // } else { + // returnData.push(responseData as IDataObject); + // } + } + return [this.helpers.returnJsonArray({})]; + } +} diff --git a/packages/nodes-base/nodes/Coda/GenericFunctions.ts b/packages/nodes-base/nodes/Coda/GenericFunctions.ts new file mode 100644 index 0000000000..ecd6bcf64b --- /dev/null +++ b/packages/nodes-base/nodes/Coda/GenericFunctions.ts @@ -0,0 +1,66 @@ +import { OptionsWithUri } from 'request'; +import { + IExecuteFunctions, + IHookFunctions, + ILoadOptionsFunctions, + IExecuteSingleFunctions, +} from 'n8n-core'; +import { IDataObject } from 'n8n-workflow'; +import { response } from 'express'; + +export async function codaApiRequest(this: IExecuteFunctions | IExecuteSingleFunctions | ILoadOptionsFunctions, method: string, resource: string, body: any = {}, qs: IDataObject = {}, uri?: string, option: IDataObject = {}): Promise { // tslint:disable-line:no-any + const credentials = this.getCredentials('codaApi'); + if (credentials === undefined) { + throw new Error('No credentials got returned!'); + } + + let options: OptionsWithUri = { + headers: { 'Authorization': `Bearer ${credentials.accessToken}`}, + method, + qs, + body, + uri: uri ||`https://coda.io/apis/v1beta1${resource}`, + json: true + }; + options = Object.assign({}, options, option); + if (Object.keys(options.body).length === 0) { + delete options.body; + } + try { + return await this.helpers.request!(options); + } catch (error) { + let errorMessage = error.message; + if (error.response.body) { + errorMessage = error.response.body.message || error.response.body.Message || error.message; + } + + throw new Error(errorMessage); + } +} + +/** + * Make an API request to paginated coda endpoint + * and return all results + */ +export async function codaApiRequestAllItems(this: IExecuteFunctions | ILoadOptionsFunctions, propertyName: string, method: string, resource: string, body: any = {}, query: IDataObject = {}): Promise { // tslint:disable-line:no-any + + const returnData: IDataObject[] = []; + + let responseData; + + query.limit = 100; + + let uri: string | undefined; + + do { + responseData = await codaApiRequest.call(this, method, resource, body, query, uri); + uri = responseData.nextPageLink; + // @ts-ignore + returnData.push.apply(returnData, responseData[propertyName]); + } while ( + responseData.nextPageLink !== undefined && + responseData.nextPageLink !== '' + ); + + return returnData; +} diff --git a/packages/nodes-base/nodes/Coda/RowDescription.ts b/packages/nodes-base/nodes/Coda/RowDescription.ts new file mode 100644 index 0000000000..831d381426 --- /dev/null +++ b/packages/nodes-base/nodes/Coda/RowDescription.ts @@ -0,0 +1,95 @@ +import { INodeProperties } from "n8n-workflow"; + +export const rowOpeations = [ + { + displayName: 'Operation', + name: 'operation', + type: 'options', + displayOptions: { + show: { + resource: [ + 'row', + ], + }, + }, + options: [ + { + name: 'Create', + value: 'create', + description: 'Create/Upsert a row', + }, + { + name: 'Update', + value: 'update', + description: 'Update row', + }, + { + name: 'Get', + value: 'get', + description: 'Get row', + }, + { + name: 'Get All', + value: 'getAll', + description: 'Get all the rows', + }, + ], + default: 'create', + description: 'The operation to perform.', + }, +] as INodeProperties[]; + +export const rowFields = [ + +/* -------------------------------------------------------------------------- */ +/* row:create */ +/* -------------------------------------------------------------------------- */ + { + displayName: 'Table', + name: 'table', + type: 'options', + required: true, + typeOptions: { + loadOptionsMethod: 'getTables', + }, + default: [], + displayOptions: { + show: { + resource: [ + 'row', + ], + operation: [ + 'create' + ] + }, + }, + description: 'The title of the task.', + }, + { + displayName: 'Additional Fields', + name: 'options', + type: 'collection', + placeholder: 'Add Field', + default: {}, + displayOptions: { + show: { + resource: [ + 'row', + ], + operation: [ + 'create', + ], + }, + }, + options: [ + { + displayName: 'Key Columns', + name: 'keyColumns', + type: 'string', + default: '', + description: `Optional column IDs, URLs, or names (fragile and discouraged), + specifying columns to be used as upsert keys. If more than one separate by ,`, + }, + ] + }, +] as INodeProperties[]; diff --git a/packages/nodes-base/nodes/Coda/coda.png b/packages/nodes-base/nodes/Coda/coda.png new file mode 100644 index 0000000000000000000000000000000000000000..cd74b6330f5f4325bac62b8cc35e170b385b640b GIT binary patch literal 1893 zcmbVM3s6%>6y5h;kus6OdZM}{PxufT_leR3Wl_3I1g>BD(_VM1+~P!lc~ zknjg3e7%%E5bie+F4U49;irobY9)ff2!SR-Kqgu#neeqH7Y;@UNs2}y)R4KvG$o6C zz-URZ)WrITZZutHYP27h4{V(o40m@nj~5~$ElQq7++>0v?hAZgZx?3tUBBB0xu3{mWm6;N5wwYc9tC* zt4*mgKJiSZyls0&yxbPZwH`ummL>dLnvd(B#U^CdH&^8(=8D(%gtQW#Edj~IhOJ{A z+1)ONn)ZZ~rDKzGqX_M95!Fp?AQC40wU<2|h?W+a9OUrXY72adDr99e$T$WKDu35w zGnklRa&=5RxUB_7Ynm#5rsz`44sZ?>2U)QJY>NR313>2goZ{aESug@7eu`lE5KhW7(zY(zA2i+?K))+JVH%+|=n;Y>1@GAY~lh7#gy6{$*kY zE0Z{Yluy;g{i=UvS3ad75r+bMsei(Fj&NF_nZ)!Lzp?? zD`ZV!2`v|UYwqfa^{8m)9jfZiPziFnVbTJyD!dqxC%Q5LiuHhq#rvrE$j55HZE!Jd zRU>k^fr`VnbZi7;A+Tb{1A7uSMpH+{0~RQu=-Pu$*hEo0cngbB5o%8U2T3TZT1evf z_kN_}b_^ycgQ^krjCd1f52|XHrl9J2_hQ67wFf-hMADsQHZ)uYAO@gdKt0VV?EV|su%_y%$w z-Gho~%V>C!_YY|Ec9(1?Y@=ug_ytpg>Ch`^oe4rYfr>25Y4}x43!YMaX(HLkI;w(b z6BHxr)TCEXw6S}=64I{y2_nZn8`p){u70nKfNX*Ij4YMT341cx0yO0+cjM2BkEV}eS)Mo<0bY< zoRY9qJ9eUZ?68-i@QLnL5k+nr`xvd?^d7ZRux#I)+Du7ztOC@@*s7!3FLd`?sT8oG zYlAT}Mm3nXvj??Qux9ltlZ&>EdY+eXf8mBXBH`GEVSUigpGk(>9?QC`ePTstdD$7&6vvyC^W$0BkBX!T(cS| z$NXK%UH<>CvycjR_aYn7><%cf0F~3}>_c?+XgYhS4>{ZcWuHKKdr)@{P4)7wWAk`M zYas9uqjhW0CL+0C>;{qln$MOQT0$tB(~KpY7p`(KQg_YCP^%*JSqKK-5TqD$BoEIl ziYqus#DC?xW2Rz@@ybm}{RDZZ1$!$j6J}~(s{z2+WjXICDo1q literal 0 HcmV?d00001 diff --git a/packages/nodes-base/package.json b/packages/nodes-base/package.json index dad780ab23..66a57b7cf4 100644 --- a/packages/nodes-base/package.json +++ b/packages/nodes-base/package.json @@ -32,6 +32,7 @@ "dist/credentials/AsanaApi.credentials.js", "dist/credentials/Aws.credentials.js", "dist/credentials/ChargebeeApi.credentials.js", + "dist/credentials/CodaApi.credentials.js", "dist/credentials/DropboxApi.credentials.js", "dist/credentials/FreshdeskApi.credentials.js", "dist/credentials/FileMaker.credentials.js", @@ -85,6 +86,7 @@ "dist/nodes/Chargebee/Chargebee.node.js", "dist/nodes/Chargebee/ChargebeeTrigger.node.js", "dist/nodes/Cron.node.js", + "dist/nodes/Coda/Coda.node.js", "dist/nodes/Dropbox/Dropbox.node.js", "dist/nodes/Discord/Discord.node.js", "dist/nodes/EditImage.node.js", From 9236d3891cbc3db75441f3f527789cad655019ee Mon Sep 17 00:00:00 2001 From: Ricardo Espinoza Date: Sat, 14 Dec 2019 11:42:32 -0500 Subject: [PATCH 2/3] :sparkles: coda node done --- packages/nodes-base/nodes/Coda/Coda.node.ts | 289 ++++++----------- .../nodes-base/nodes/Coda/GenericFunctions.ts | 2 - .../nodes-base/nodes/Coda/RowDescription.ts | 301 +++++++++++++++++- 3 files changed, 383 insertions(+), 209 deletions(-) diff --git a/packages/nodes-base/nodes/Coda/Coda.node.ts b/packages/nodes-base/nodes/Coda/Coda.node.ts index 605db290f6..38110a228a 100644 --- a/packages/nodes-base/nodes/Coda/Coda.node.ts +++ b/packages/nodes-base/nodes/Coda/Coda.node.ts @@ -89,211 +89,102 @@ export class Coda implements INodeType { }; async execute(this: IExecuteFunctions): Promise { - const items = this.getInputData(); const returnData: IDataObject[] = []; + const items = this.getInputData(); + const credentials = this.getCredentials('codaApi'); + const docId = credentials!.docId; const length = items.length as unknown as number; let responseData; const qs: IDataObject = {}; const resource = this.getNodeParameter('resource', 0) as string; const operation = this.getNodeParameter('operation', 0) as string; - - for (let i = 0; i < length; i++) { - // if (resource === 'task') { - // //https://developer.getflow.com/api/#tasks_create-task - // if (operation === 'create') { - // const workspaceId = this.getNodeParameter('workspaceId', i) as string; - // const name = this.getNodeParameter('name', i) as string; - // const additionalFields = this.getNodeParameter('additionalFields', i) as IDataObject; - // const body: ITask = { - // organization_id: credentials.organizationId as number, - // }; - // const task: TaskInfo = { - // name, - // workspace_id: parseInt(workspaceId, 10) - // }; - // if (additionalFields.ownerId) { - // task.owner_id = parseInt(additionalFields.ownerId as string, 10); - // } - // if (additionalFields.listId) { - // task.list_id = parseInt(additionalFields.listId as string, 10); - // } - // if (additionalFields.startsOn) { - // task.starts_on = additionalFields.startsOn as string; - // } - // if (additionalFields.dueOn) { - // task.due_on = additionalFields.dueOn as string; - // } - // if (additionalFields.mirrorParentSubscribers) { - // task.mirror_parent_subscribers = additionalFields.mirrorParentSubscribers as boolean; - // } - // if (additionalFields.mirrorParentTags) { - // task.mirror_parent_tags = additionalFields.mirrorParentTags as boolean; - // } - // if (additionalFields.noteContent) { - // task.note_content = additionalFields.noteContent as string; - // } - // if (additionalFields.noteMimeType) { - // task.note_mime_type = additionalFields.noteMimeType as string; - // } - // if (additionalFields.parentId) { - // task.parent_id = parseInt(additionalFields.parentId as string, 10); - // } - // if (additionalFields.positionList) { - // task.position_list = additionalFields.positionList as number; - // } - // if (additionalFields.positionUpcoming) { - // task.position_upcoming = additionalFields.positionUpcoming as number; - // } - // if (additionalFields.position) { - // task.position = additionalFields.position as number; - // } - // if (additionalFields.sectionId) { - // task.section_id = additionalFields.sectionId as number; - // } - // if (additionalFields.tags) { - // task.tags = (additionalFields.tags as string).split(','); - // } - // body.task = task; - // try { - // responseData = await flowApiRequest.call(this, 'POST', '/tasks', body); - // responseData = responseData.task; - // } catch (err) { - // throw new Error(`Flow Error: ${err.message}`); - // } - // } - // //https://developer.getflow.com/api/#tasks_update-a-task - // if (operation === 'update') { - // const workspaceId = this.getNodeParameter('workspaceId', i) as string; - // const taskId = this.getNodeParameter('taskId', i) as string; - // const updateFields = this.getNodeParameter('updateFields', i) as IDataObject; - // const body: ITask = { - // organization_id: credentials.organizationId as number, - // }; - // const task: TaskInfo = { - // workspace_id: parseInt(workspaceId, 10), - // id: parseInt(taskId, 10), - // }; - // if (updateFields.name) { - // task.name = updateFields.name as string; - // } - // if (updateFields.ownerId) { - // task.owner_id = parseInt(updateFields.ownerId as string, 10); - // } - // if (updateFields.listId) { - // task.list_id = parseInt(updateFields.listId as string, 10); - // } - // if (updateFields.startsOn) { - // task.starts_on = updateFields.startsOn as string; - // } - // if (updateFields.dueOn) { - // task.due_on = updateFields.dueOn as string; - // } - // if (updateFields.mirrorParentSubscribers) { - // task.mirror_parent_subscribers = updateFields.mirrorParentSubscribers as boolean; - // } - // if (updateFields.mirrorParentTags) { - // task.mirror_parent_tags = updateFields.mirrorParentTags as boolean; - // } - // if (updateFields.noteContent) { - // task.note_content = updateFields.noteContent as string; - // } - // if (updateFields.noteMimeType) { - // task.note_mime_type = updateFields.noteMimeType as string; - // } - // if (updateFields.parentId) { - // task.parent_id = parseInt(updateFields.parentId as string, 10); - // } - // if (updateFields.positionList) { - // task.position_list = updateFields.positionList as number; - // } - // if (updateFields.positionUpcoming) { - // task.position_upcoming = updateFields.positionUpcoming as number; - // } - // if (updateFields.position) { - // task.position = updateFields.position as number; - // } - // if (updateFields.sectionId) { - // task.section_id = updateFields.sectionId as number; - // } - // if (updateFields.tags) { - // task.tags = (updateFields.tags as string).split(','); - // } - // if (updateFields.completed) { - // task.completed = updateFields.completed as boolean; - // } - // body.task = task; - // try { - // responseData = await flowApiRequest.call(this, 'PUT', `/tasks/${taskId}`, body); - // responseData = responseData.task; - // } catch (err) { - // throw new Error(`Flow Error: ${err.message}`); - // } - // } - // //https://developer.getflow.com/api/#tasks_get-task - // if (operation === 'get') { - // const taskId = this.getNodeParameter('taskId', i) as string; - // const filters = this.getNodeParameter('filters', i) as IDataObject; - // qs.organization_id = credentials.organizationId as number; - // if (filters.include) { - // qs.include = (filters.include as string[]).join(','); - // } - // try { - // responseData = await flowApiRequest.call(this,'GET', `/tasks/${taskId}`, {}, qs); - // } catch (err) { - // throw new Error(`Flow Error: ${err.message}`); - // } - // } - // //https://developer.getflow.com/api/#tasks_get-tasks - // if (operation === 'getAll') { - // const returnAll = this.getNodeParameter('returnAll', i) as boolean; - // const filters = this.getNodeParameter('filters', i) as IDataObject; - // qs.organization_id = credentials.organizationId as number; - // if (filters.include) { - // qs.include = (filters.include as string[]).join(','); - // } - // if (filters.order) { - // qs.order = filters.order as string; - // } - // if (filters.workspaceId) { - // qs.workspace_id = filters.workspaceId as string; - // } - // if (filters.createdBefore) { - // qs.created_before = filters.createdBefore as string; - // } - // if (filters.createdAfter) { - // qs.created_after = filters.createdAfter as string; - // } - // if (filters.updateBefore) { - // qs.updated_before = filters.updateBefore as string; - // } - // if (filters.updateAfter) { - // qs.updated_after = filters.updateAfter as string; - // } - // if (filters.deleted) { - // qs.deleted = filters.deleted as boolean; - // } - // if (filters.cleared) { - // qs.cleared = filters.cleared as boolean; - // } - // try { - // if (returnAll === true) { - // responseData = await FlowApiRequestAllItems.call(this, 'tasks', 'GET', '/tasks', {}, qs); - // } else { - // qs.limit = this.getNodeParameter('limit', i) as number; - // responseData = await flowApiRequest.call(this, 'GET', '/tasks', {}, qs); - // responseData = responseData.tasks; - // } - // } catch (err) { - // throw new Error(`Flow Error: ${err.message}`); - // } - // } - // } - // if (Array.isArray(responseData)) { - // returnData.push.apply(returnData, responseData as IDataObject[]); - // } else { - // returnData.push(responseData as IDataObject); - // } + if (resource === 'row') { + //https://coda.io/developers/apis/v1beta1#operation/upsertRows + if (operation === 'create') { + const tableId = this.getNodeParameter('tableId', 0) as string; + const additionalFields = this.getNodeParameter('additionalFields', 0) as IDataObject; + const endpoint = `/docs/${docId}/tables/${tableId}/rows`; + if (additionalFields.keyColumns) { + // @ts-ignore + items[0].json['keyColumns'] = additionalFields.keyColumns.split(',') as string[]; + } + if (additionalFields.disableParsing) { + qs.disableParsing = additionalFields.disableParsing as boolean; + } + try { + responseData = await codaApiRequest.call(this, 'POST', endpoint, items[0].json, qs); + } catch (err) { + throw new Error(`Coda Error: ${err.message}`); + } + } + //https://coda.io/developers/apis/v1beta1#operation/getRow + if (operation === 'get') { + const tableId = this.getNodeParameter('tableId', 0) as string; + const rowId = this.getNodeParameter('rowId', 0) as string; + const filters = this.getNodeParameter('filters', 0) as IDataObject; + const endpoint = `/docs/${docId}/tables/${tableId}/rows/${rowId}`; + if (filters.useColumnNames) { + qs.useColumnNames = filters.useColumnNames as boolean; + } + if (filters.valueFormat) { + qs.valueFormat = filters.valueFormat as string; + } + try { + responseData = await codaApiRequest.call(this, 'GET', endpoint, {}, qs); + } catch (err) { + throw new Error(`Coda Error: ${err.message}`); + } + } + //https://coda.io/developers/apis/v1beta1#operation/listRows + if (operation === 'getAll') { + const returnAll = this.getNodeParameter('returnAll', 0) as boolean; + const tableId = this.getNodeParameter('tableId', 0) as string; + const filters = this.getNodeParameter('filters', 0) as IDataObject; + const endpoint = `/docs/${docId}/tables/${tableId}/rows`; + if (filters.useColumnNames) { + qs.useColumnNames = filters.useColumnNames as boolean; + } + if (filters.valueFormat) { + qs.valueFormat = filters.valueFormat as string; + } + if (filters.sortBy) { + qs.sortBy = filters.sortBy as string; + } + if (filters.visibleOnly) { + qs.visibleOnly = filters.visibleOnly as boolean; + } + try { + if (returnAll === true) { + responseData = await codaApiRequestAllItems.call(this, 'items', 'GET', endpoint, {}, qs); + } else { + qs.limit = this.getNodeParameter('limit', 0) as number; + responseData = await codaApiRequest.call(this, 'GET', endpoint, {}, qs); + responseData = responseData.items; + } + } catch (err) { + throw new Error(`Flow Error: ${err.message}`); + } + } + //https://coda.io/developers/apis/v1beta1#operation/deleteRows + if (operation === 'delete') { + const tableId = this.getNodeParameter('tableId', 0) as string; + const rowId = this.getNodeParameter('rowId', 0) as string; + const body = {}; + const endpoint = `/docs/${docId}/tables/${tableId}/rows`; + try { + // @ts-ignore + body['rowIds'] = rowId.split(',') as string[]; + responseData = await codaApiRequest.call(this, 'DELETE', endpoint, body, qs); + } catch (err) { + throw new Error(`Coda Error: ${err.message}`); + } + } + if (Array.isArray(responseData)) { + returnData.push.apply(returnData, responseData as IDataObject[]); + } else { + returnData.push(responseData as IDataObject); + } } - return [this.helpers.returnJsonArray({})]; + return [this.helpers.returnJsonArray(responseData)]; } } diff --git a/packages/nodes-base/nodes/Coda/GenericFunctions.ts b/packages/nodes-base/nodes/Coda/GenericFunctions.ts index ecd6bcf64b..2d26d593a7 100644 --- a/packages/nodes-base/nodes/Coda/GenericFunctions.ts +++ b/packages/nodes-base/nodes/Coda/GenericFunctions.ts @@ -1,12 +1,10 @@ import { OptionsWithUri } from 'request'; import { IExecuteFunctions, - IHookFunctions, ILoadOptionsFunctions, IExecuteSingleFunctions, } from 'n8n-core'; import { IDataObject } from 'n8n-workflow'; -import { response } from 'express'; export async function codaApiRequest(this: IExecuteFunctions | IExecuteSingleFunctions | ILoadOptionsFunctions, method: string, resource: string, body: any = {}, qs: IDataObject = {}, uri?: string, option: IDataObject = {}): Promise { // tslint:disable-line:no-any const credentials = this.getCredentials('codaApi'); diff --git a/packages/nodes-base/nodes/Coda/RowDescription.ts b/packages/nodes-base/nodes/Coda/RowDescription.ts index 831d381426..d9520266d6 100644 --- a/packages/nodes-base/nodes/Coda/RowDescription.ts +++ b/packages/nodes-base/nodes/Coda/RowDescription.ts @@ -18,11 +18,6 @@ export const rowOpeations = [ value: 'create', description: 'Create/Upsert a row', }, - { - name: 'Update', - value: 'update', - description: 'Update row', - }, { name: 'Get', value: 'get', @@ -33,6 +28,11 @@ export const rowOpeations = [ value: 'getAll', description: 'Get all the rows', }, + { + name: 'Delete', + value: 'delete', + description: 'Delete one or multiple rows', + }, ], default: 'create', description: 'The operation to perform.', @@ -46,7 +46,7 @@ export const rowFields = [ /* -------------------------------------------------------------------------- */ { displayName: 'Table', - name: 'table', + name: 'tableId', type: 'options', required: true, typeOptions: { @@ -63,11 +63,11 @@ export const rowFields = [ ] }, }, - description: 'The title of the task.', + description: 'Tables on document', }, { displayName: 'Additional Fields', - name: 'options', + name: 'additionalFields', type: 'collection', placeholder: 'Add Field', default: {}, @@ -90,6 +90,291 @@ export const rowFields = [ description: `Optional column IDs, URLs, or names (fragile and discouraged), specifying columns to be used as upsert keys. If more than one separate by ,`, }, + { + displayName: 'Disable Parsing', + name: 'disableParsing', + type: 'boolean', + default: false, + description: `If true, the API will not attempt to parse the data in any way.`, + }, ] }, + +/* -------------------------------------------------------------------------- */ +/* row:get */ +/* -------------------------------------------------------------------------- */ +{ + displayName: 'Table', + name: 'tableId', + type: 'options', + required: true, + typeOptions: { + loadOptionsMethod: 'getTables', + }, + default: [], + displayOptions: { + show: { + resource: [ + 'row', + ], + operation: [ + 'get' + ] + }, + }, + description: 'Tables on document', +}, +{ + displayName: 'Row ID', + name: 'rowId', + type: 'string', + required: true, + default: '', + displayOptions: { + show: { + resource: [ + 'row', + ], + operation: [ + 'get' + ] + }, + }, + description: `ID or name of the row. Names are discouraged because they're easily prone to being changed by users. + If you're using a name, be sure to URI-encode it. + If there are multiple rows with the same value in the identifying column, an arbitrary one will be selected`, +}, +{ + displayName: 'Filters', + name: 'filters', + type: 'collection', + placeholder: 'Add Filter', + default: {}, + displayOptions: { + show: { + resource: [ + 'row', + ], + operation: [ + 'get', + ], + }, + }, + options: [ + { + displayName: 'Use Column Names', + name: 'useColumnNames', + type: 'boolean', + default: false, + description: `Use column names instead of column IDs in the returned output.
+ This is generally discouraged as it is fragile. If columns are renamed,
+ code using original names may throw errors.`, + }, + { + displayName: 'ValueFormat', + name: 'valueFormat', + type: 'options', + default: [], + options: [ + { + name: 'Simple', + value: 'simple', + }, + { + name: 'Simple With Arrays', + value: 'simpleWithArrays', + }, + { + name: 'Rich', + value: 'rich', + }, + ], + description: `The format that cell values are returned as.`, + }, + ] +}, + +/* -------------------------------------------------------------------------- */ +/* get:all */ +/* -------------------------------------------------------------------------- */ +{ + displayName: 'Table', + name: 'tableId', + type: 'options', + required: true, + typeOptions: { + loadOptionsMethod: 'getTables', + }, + default: [], + displayOptions: { + show: { + resource: [ + 'row', + ], + operation: [ + 'getAll' + ] + }, + }, + description: 'Tables on document', +}, +{ + displayName: 'Return All', + name: 'returnAll', + type: 'boolean', + displayOptions: { + show: { + resource: [ + 'row', + ], + operation: [ + 'getAll' + ] + }, + }, + default: false, + description: 'If all results should be returned or only up to a given limit.', +}, +{ + displayName: 'Limit', + name: 'limit', + type: 'number', + displayOptions: { + show: { + resource: [ + 'row', + ], + operation: [ + 'getAll' + ], + returnAll: [ + false, + ], + }, + }, + typeOptions: { + minValue: 1, + maxValue: 100, + }, + default: 50, + description: 'How many results to return.', +}, +{ + displayName: 'Filters', + name: 'filters', + type: 'collection', + placeholder: 'Add Filter', + default: {}, + displayOptions: { + show: { + resource: [ + 'row', + ], + operation: [ + 'getAll', + ], + }, + }, + options: [ + { + displayName: 'Use Column Names', + name: 'useColumnNames', + type: 'boolean', + default: false, + description: `Use column names instead of column IDs in the returned output.
+ This is generally discouraged as it is fragile. If columns are renamed,
+ code using original names may throw errors.`, + }, + { + displayName: 'ValueFormat', + name: 'valueFormat', + type: 'options', + default: [], + options: [ + { + name: 'Simple', + value: 'simple', + }, + { + name: 'Simple With Arrays', + value: 'simpleWithArrays', + }, + { + name: 'Rich', + value: 'rich', + }, + ], + description: `The format that cell values are returned as.`, + }, + { + displayName: 'Sort By', + name: 'sortBy', + type: 'options', + default: [], + options: [ + { + name: 'Created At', + value: 'createdAt', + }, + { + name: 'Natural', + value: 'natural', + }, + ], + description: `Specifies the sort order of the rows returned. + If left unspecified, rows are returned by creation time ascending.`, + }, + { + displayName: 'Visible Only', + name: 'visibleOnly', + type: 'boolean', + default: false, + description: `If true, returns only visible rows and columns for the table.`, + }, + ] +}, + +/* -------------------------------------------------------------------------- */ +/* row:delete */ +/* -------------------------------------------------------------------------- */ +{ + displayName: 'Table', + name: 'tableId', + type: 'options', + required: true, + typeOptions: { + loadOptionsMethod: 'getTables', + }, + default: [], + displayOptions: { + show: { + resource: [ + 'row', + ], + operation: [ + 'delete' + ] + }, + }, + description: 'Tables on document', +}, +{ + displayName: 'Row ID', + name: 'rowId', + type: 'string', + required: true, + default: '', + displayOptions: { + show: { + resource: [ + 'row', + ], + operation: [ + 'delete' + ] + }, + }, + description: `Row IDs to delete separated by ,.`, +}, + ] as INodeProperties[]; From e07ea137087381d2ba09c07990395ecbfd4b8b21 Mon Sep 17 00:00:00 2001 From: Ricardo Espinoza Date: Mon, 16 Dec 2019 11:40:44 -0500 Subject: [PATCH 3/3] :bug: fixes --- .../credentials/CodaApi.credentials.ts | 6 - packages/nodes-base/nodes/Coda/Coda.node.ts | 35 +- .../nodes-base/nodes/Coda/RowDescription.ts | 584 ++++++++++-------- 3 files changed, 351 insertions(+), 274 deletions(-) diff --git a/packages/nodes-base/credentials/CodaApi.credentials.ts b/packages/nodes-base/credentials/CodaApi.credentials.ts index c7e8befe4c..226dd6ee68 100644 --- a/packages/nodes-base/credentials/CodaApi.credentials.ts +++ b/packages/nodes-base/credentials/CodaApi.credentials.ts @@ -7,12 +7,6 @@ export class CodaApi implements ICredentialType { name = 'codaApi'; displayName = 'Coda API'; properties = [ - { - displayName: 'Doc ID', - name: 'docId', - type: 'string' as NodePropertyTypes, - default: '', - }, { displayName: 'Access Token', name: 'accessToken', diff --git a/packages/nodes-base/nodes/Coda/Coda.node.ts b/packages/nodes-base/nodes/Coda/Coda.node.ts index 38110a228a..4a54bf41c0 100644 --- a/packages/nodes-base/nodes/Coda/Coda.node.ts +++ b/packages/nodes-base/nodes/Coda/Coda.node.ts @@ -63,24 +63,23 @@ export class Coda implements INodeType { methods = { loadOptions: { - // Get all the available tables to display them to user so that he can + // Get all the available docs to display them to user so that he can // select them easily - async getTables(this: ILoadOptionsFunctions): Promise { + async getDocs(this: ILoadOptionsFunctions): Promise { const returnData: INodePropertyOptions[] = []; - const credentials = this.getCredentials('codaApi'); const qs = {}; - let tables; + let docs; try { - tables = await codaApiRequestAllItems.call(this,'items', 'GET', `/docs/${credentials!.docId}/tables`, {}, qs); + docs = await codaApiRequestAllItems.call(this,'items', 'GET', `/docs`, {}, qs); } catch (err) { throw new Error(`Coda Error: ${err}`); } - for (const table of tables) { - const tableName = table.name; - const tableId = table.id; + for (const doc of docs) { + const docName = doc.name; + const docId = doc.id; returnData.push({ - name: tableName, - value: tableId, + name: docName, + value: docId, }); } return returnData; @@ -91,9 +90,6 @@ export class Coda implements INodeType { async execute(this: IExecuteFunctions): Promise { const returnData: IDataObject[] = []; const items = this.getInputData(); - const credentials = this.getCredentials('codaApi'); - const docId = credentials!.docId; - const length = items.length as unknown as number; let responseData; const qs: IDataObject = {}; const resource = this.getNodeParameter('resource', 0) as string; @@ -101,6 +97,7 @@ export class Coda implements INodeType { if (resource === 'row') { //https://coda.io/developers/apis/v1beta1#operation/upsertRows if (operation === 'create') { + const docId = this.getNodeParameter('docId', 0) as string; const tableId = this.getNodeParameter('tableId', 0) as string; const additionalFields = this.getNodeParameter('additionalFields', 0) as IDataObject; const endpoint = `/docs/${docId}/tables/${tableId}/rows`; @@ -119,6 +116,7 @@ export class Coda implements INodeType { } //https://coda.io/developers/apis/v1beta1#operation/getRow if (operation === 'get') { + const docId = this.getNodeParameter('docId', 0) as string; const tableId = this.getNodeParameter('tableId', 0) as string; const rowId = this.getNodeParameter('rowId', 0) as string; const filters = this.getNodeParameter('filters', 0) as IDataObject; @@ -137,6 +135,7 @@ export class Coda implements INodeType { } //https://coda.io/developers/apis/v1beta1#operation/listRows if (operation === 'getAll') { + const docId = this.getNodeParameter('docId', 0) as string; const returnAll = this.getNodeParameter('returnAll', 0) as boolean; const tableId = this.getNodeParameter('tableId', 0) as string; const filters = this.getNodeParameter('filters', 0) as IDataObject; @@ -167,13 +166,19 @@ export class Coda implements INodeType { } //https://coda.io/developers/apis/v1beta1#operation/deleteRows if (operation === 'delete') { + const docId = this.getNodeParameter('docId', 0) as string; const tableId = this.getNodeParameter('tableId', 0) as string; - const rowId = this.getNodeParameter('rowId', 0) as string; const body = {}; + let rowIds = ''; const endpoint = `/docs/${docId}/tables/${tableId}/rows`; + for (let i = 0; i < items.length; i++) { + const rowId = this.getNodeParameter('rowId', i) as string; + rowIds += rowId; + } + // @ts-ignore + body['rowIds'] = rowIds.split(',') as string[]; try { // @ts-ignore - body['rowIds'] = rowId.split(',') as string[]; responseData = await codaApiRequest.call(this, 'DELETE', endpoint, body, qs); } catch (err) { throw new Error(`Coda Error: ${err.message}`); diff --git a/packages/nodes-base/nodes/Coda/RowDescription.ts b/packages/nodes-base/nodes/Coda/RowDescription.ts index d9520266d6..70529412ea 100644 --- a/packages/nodes-base/nodes/Coda/RowDescription.ts +++ b/packages/nodes-base/nodes/Coda/RowDescription.ts @@ -45,12 +45,12 @@ export const rowFields = [ /* row:create */ /* -------------------------------------------------------------------------- */ { - displayName: 'Table', - name: 'tableId', + displayName: 'Doc', + name: 'docId', type: 'options', required: true, typeOptions: { - loadOptionsMethod: 'getTables', + loadOptionsMethod: 'getDocs', }, default: [], displayOptions: { @@ -63,7 +63,27 @@ export const rowFields = [ ] }, }, - description: 'Tables on document', + description: 'ID of the doc.', + }, + { + displayName: 'Table ID', + name: 'tableId', + type: 'string', + required: true, + default: [], + displayOptions: { + show: { + resource: [ + 'row', + ], + operation: [ + 'create' + ] + }, + }, + description: `ID or name of the table. Names are discouraged because
+ they're easily prone to being changed by users.
+ If you're using a name, be sure to URI-encode it.`, }, { displayName: 'Additional Fields', @@ -103,278 +123,336 @@ export const rowFields = [ /* -------------------------------------------------------------------------- */ /* row:get */ /* -------------------------------------------------------------------------- */ -{ - displayName: 'Table', - name: 'tableId', - type: 'options', - required: true, - typeOptions: { - loadOptionsMethod: 'getTables', + { + displayName: 'Doc', + name: 'docId', + type: 'options', + required: true, + typeOptions: { + loadOptionsMethod: 'getDocs', + }, + default: [], + displayOptions: { + show: { + resource: [ + 'row', + ], + operation: [ + 'get' + ] + }, + }, + description: 'ID of the doc.', }, - default: [], - displayOptions: { - show: { - resource: [ - 'row', - ], - operation: [ - 'get' - ] + { + displayName: 'Table ID', + name: 'tableId', + type: 'string', + required: true, + default: [], + displayOptions: { + show: { + resource: [ + 'row', + ], + operation: [ + 'get' + ] + }, }, + description: `ID or name of the table. Names are discouraged because
+ they're easily prone to being changed by users.
+ If you're using a name, be sure to URI-encode it.`, }, - description: 'Tables on document', -}, -{ - displayName: 'Row ID', - name: 'rowId', - type: 'string', - required: true, - default: '', - displayOptions: { - show: { - resource: [ - 'row', - ], - operation: [ - 'get' - ] + { + displayName: 'Row ID', + name: 'rowId', + type: 'string', + required: true, + default: '', + displayOptions: { + show: { + resource: [ + 'row', + ], + operation: [ + 'get' + ] + }, }, + description: `ID or name of the row. Names are discouraged because they're easily prone to being changed by users. + If you're using a name, be sure to URI-encode it. + If there are multiple rows with the same value in the identifying column, an arbitrary one will be selected`, }, - description: `ID or name of the row. Names are discouraged because they're easily prone to being changed by users. - If you're using a name, be sure to URI-encode it. - If there are multiple rows with the same value in the identifying column, an arbitrary one will be selected`, -}, -{ - displayName: 'Filters', - name: 'filters', - type: 'collection', - placeholder: 'Add Filter', - default: {}, - displayOptions: { - show: { - resource: [ - 'row', - ], - operation: [ - 'get', - ], + { + displayName: 'Filters', + name: 'filters', + type: 'collection', + placeholder: 'Add Filter', + default: {}, + displayOptions: { + show: { + resource: [ + 'row', + ], + operation: [ + 'get', + ], + }, }, + options: [ + { + displayName: 'Use Column Names', + name: 'useColumnNames', + type: 'boolean', + default: false, + description: `Use column names instead of column IDs in the returned output.
+ This is generally discouraged as it is fragile. If columns are renamed,
+ code using original names may throw errors.`, + }, + { + displayName: 'ValueFormat', + name: 'valueFormat', + type: 'options', + default: [], + options: [ + { + name: 'Simple', + value: 'simple', + }, + { + name: 'Simple With Arrays', + value: 'simpleWithArrays', + }, + { + name: 'Rich', + value: 'rich', + }, + ], + description: `The format that cell values are returned as.`, + }, + ] }, - options: [ - { - displayName: 'Use Column Names', - name: 'useColumnNames', - type: 'boolean', - default: false, - description: `Use column names instead of column IDs in the returned output.
- This is generally discouraged as it is fragile. If columns are renamed,
- code using original names may throw errors.`, - }, - { - displayName: 'ValueFormat', - name: 'valueFormat', - type: 'options', - default: [], - options: [ - { - name: 'Simple', - value: 'simple', - }, - { - name: 'Simple With Arrays', - value: 'simpleWithArrays', - }, - { - name: 'Rich', - value: 'rich', - }, - ], - description: `The format that cell values are returned as.`, - }, - ] -}, - /* -------------------------------------------------------------------------- */ /* get:all */ /* -------------------------------------------------------------------------- */ -{ - displayName: 'Table', - name: 'tableId', - type: 'options', - required: true, - typeOptions: { - loadOptionsMethod: 'getTables', + { + displayName: 'Doc', + name: 'docId', + type: 'options', + required: true, + typeOptions: { + loadOptionsMethod: 'getDocs', + }, + default: [], + displayOptions: { + show: { + resource: [ + 'row', + ], + operation: [ + 'getAll' + ] + }, + }, + description: 'ID of the doc.', }, - default: [], - displayOptions: { - show: { - resource: [ - 'row', - ], - operation: [ - 'getAll' - ] + { + displayName: 'Table ID', + name: 'tableId', + type: 'string', + required: true, + default: [], + displayOptions: { + show: { + resource: [ + 'row', + ], + operation: [ + 'getAll' + ] + }, }, + description: `ID or name of the table. Names are discouraged because
+ they're easily prone to being changed by users.
+ If you're using a name, be sure to URI-encode it.`, }, - description: 'Tables on document', -}, -{ - displayName: 'Return All', - name: 'returnAll', - type: 'boolean', - displayOptions: { - show: { - resource: [ - 'row', - ], - operation: [ - 'getAll' - ] + { + displayName: 'Return All', + name: 'returnAll', + type: 'boolean', + displayOptions: { + show: { + resource: [ + 'row', + ], + operation: [ + 'getAll' + ] + }, }, + default: false, + description: 'If all results should be returned or only up to a given limit.', }, - default: false, - description: 'If all results should be returned or only up to a given limit.', -}, -{ - displayName: 'Limit', - name: 'limit', - type: 'number', - displayOptions: { - show: { - resource: [ - 'row', - ], - operation: [ - 'getAll' - ], - returnAll: [ - false, - ], + { + displayName: 'Limit', + name: 'limit', + type: 'number', + displayOptions: { + show: { + resource: [ + 'row', + ], + operation: [ + 'getAll' + ], + returnAll: [ + false, + ], + }, }, + typeOptions: { + minValue: 1, + maxValue: 100, + }, + default: 50, + description: 'How many results to return.', }, - typeOptions: { - minValue: 1, - maxValue: 100, + { + displayName: 'Filters', + name: 'filters', + type: 'collection', + placeholder: 'Add Filter', + default: {}, + displayOptions: { + show: { + resource: [ + 'row', + ], + operation: [ + 'getAll', + ], + }, + }, + options: [ + { + displayName: 'Use Column Names', + name: 'useColumnNames', + type: 'boolean', + default: false, + description: `Use column names instead of column IDs in the returned output.
+ This is generally discouraged as it is fragile. If columns are renamed,
+ code using original names may throw errors.`, + }, + { + displayName: 'ValueFormat', + name: 'valueFormat', + type: 'options', + default: [], + options: [ + { + name: 'Simple', + value: 'simple', + }, + { + name: 'Simple With Arrays', + value: 'simpleWithArrays', + }, + { + name: 'Rich', + value: 'rich', + }, + ], + description: `The format that cell values are returned as.`, + }, + { + displayName: 'Sort By', + name: 'sortBy', + type: 'options', + default: [], + options: [ + { + name: 'Created At', + value: 'createdAt', + }, + { + name: 'Natural', + value: 'natural', + }, + ], + description: `Specifies the sort order of the rows returned. + If left unspecified, rows are returned by creation time ascending.`, + }, + { + displayName: 'Visible Only', + name: 'visibleOnly', + type: 'boolean', + default: false, + description: `If true, returns only visible rows and columns for the table.`, + }, + ] }, - default: 50, - description: 'How many results to return.', -}, -{ - displayName: 'Filters', - name: 'filters', - type: 'collection', - placeholder: 'Add Filter', - default: {}, - displayOptions: { - show: { - resource: [ - 'row', - ], - operation: [ - 'getAll', - ], - }, - }, - options: [ - { - displayName: 'Use Column Names', - name: 'useColumnNames', - type: 'boolean', - default: false, - description: `Use column names instead of column IDs in the returned output.
- This is generally discouraged as it is fragile. If columns are renamed,
- code using original names may throw errors.`, - }, - { - displayName: 'ValueFormat', - name: 'valueFormat', - type: 'options', - default: [], - options: [ - { - name: 'Simple', - value: 'simple', - }, - { - name: 'Simple With Arrays', - value: 'simpleWithArrays', - }, - { - name: 'Rich', - value: 'rich', - }, - ], - description: `The format that cell values are returned as.`, - }, - { - displayName: 'Sort By', - name: 'sortBy', - type: 'options', - default: [], - options: [ - { - name: 'Created At', - value: 'createdAt', - }, - { - name: 'Natural', - value: 'natural', - }, - ], - description: `Specifies the sort order of the rows returned. - If left unspecified, rows are returned by creation time ascending.`, - }, - { - displayName: 'Visible Only', - name: 'visibleOnly', - type: 'boolean', - default: false, - description: `If true, returns only visible rows and columns for the table.`, - }, - ] -}, - /* -------------------------------------------------------------------------- */ /* row:delete */ /* -------------------------------------------------------------------------- */ -{ - displayName: 'Table', - name: 'tableId', - type: 'options', - required: true, - typeOptions: { - loadOptionsMethod: 'getTables', - }, - default: [], - displayOptions: { - show: { - resource: [ - 'row', - ], - operation: [ - 'delete' - ] + { + displayName: 'Doc', + name: 'docId', + type: 'options', + required: true, + typeOptions: { + loadOptionsMethod: 'getDocs', }, - }, - description: 'Tables on document', -}, -{ - displayName: 'Row ID', - name: 'rowId', - type: 'string', - required: true, - default: '', - displayOptions: { - show: { - resource: [ - 'row', - ], - operation: [ - 'delete' - ] + default: [], + displayOptions: { + show: { + resource: [ + 'row', + ], + operation: [ + 'delete' + ] + }, }, + description: 'ID of the doc.', + }, + { + displayName: 'Table ID', + name: 'tableId', + type: 'string', + required: true, + default: [], + displayOptions: { + show: { + resource: [ + 'row', + ], + operation: [ + 'delete' + ] + }, + }, + description: `ID or name of the table. Names are discouraged because
+ they're easily prone to being changed by users.
+ If you're using a name, be sure to URI-encode it.`, + }, + { + displayName: 'Row ID', + name: 'rowId', + type: 'string', + required: true, + default: '', + displayOptions: { + show: { + resource: [ + 'row', + ], + operation: [ + 'delete' + ] + }, + }, + description: `Row IDs to delete separated by ,.`, }, - description: `Row IDs to delete separated by ,.`, -}, ] as INodeProperties[];