From 60be31d41015be10fa7ddce1bc5330f78b00dcf5 Mon Sep 17 00:00:00 2001 From: Jan Oberhauser Date: Wed, 25 Nov 2020 13:09:58 +0100 Subject: [PATCH] :zap: Improvements to Quick Base Node --- .../credentials/QuickBaseApi.credentials.ts | 4 +- .../nodes/QuickBase/FieldDescription.ts | 2 +- .../nodes/QuickBase/FileDescription.ts | 4 +- .../nodes/QuickBase/GenericFunctions.ts | 14 ++++-- .../nodes/QuickBase/QuickBase.node.ts | 47 +++++++++--------- .../nodes/QuickBase/RecordDescription.ts | 5 +- .../nodes/QuickBase/ReportDescription.ts | 8 +-- .../nodes-base/nodes/QuickBase/quickbase.png | Bin 5062 -> 1258 bytes 8 files changed, 47 insertions(+), 37 deletions(-) diff --git a/packages/nodes-base/credentials/QuickBaseApi.credentials.ts b/packages/nodes-base/credentials/QuickBaseApi.credentials.ts index f0f67ef83a..b243bf4652 100644 --- a/packages/nodes-base/credentials/QuickBaseApi.credentials.ts +++ b/packages/nodes-base/credentials/QuickBaseApi.credentials.ts @@ -13,13 +13,15 @@ export class QuickBaseApi implements ICredentialType { name: 'hostname', type: 'string' as NodePropertyTypes, default: '', + required: true, placeholder: 'demo.quickbase.com', - }, + }, { displayName: 'User Token', name: 'userToken', type: 'string' as NodePropertyTypes, default: '', + required: true, }, ]; } diff --git a/packages/nodes-base/nodes/QuickBase/FieldDescription.ts b/packages/nodes-base/nodes/QuickBase/FieldDescription.ts index 81b6f5056e..43423d0e5d 100644 --- a/packages/nodes-base/nodes/QuickBase/FieldDescription.ts +++ b/packages/nodes-base/nodes/QuickBase/FieldDescription.ts @@ -21,7 +21,7 @@ export const fieldOperations = [ description: 'Get all fields', }, ], - default: 'create', + default: 'getAll', description: 'The operation to perform.', }, ] as INodeProperties[]; diff --git a/packages/nodes-base/nodes/QuickBase/FileDescription.ts b/packages/nodes-base/nodes/QuickBase/FileDescription.ts index dc88602ab5..8efa59ef2f 100644 --- a/packages/nodes-base/nodes/QuickBase/FileDescription.ts +++ b/packages/nodes-base/nodes/QuickBase/FileDescription.ts @@ -52,7 +52,7 @@ export const fileFields = [ ], }, }, - description: 'The table identifier', + description: 'The table identifier.', }, { displayName: 'Record ID', @@ -71,7 +71,7 @@ export const fileFields = [ ], }, }, - description: 'The unique identifier of the record', + description: 'The unique identifier of the record.', }, { displayName: 'Field ID', diff --git a/packages/nodes-base/nodes/QuickBase/GenericFunctions.ts b/packages/nodes-base/nodes/QuickBase/GenericFunctions.ts index aa6fd07e4d..e62221b989 100644 --- a/packages/nodes-base/nodes/QuickBase/GenericFunctions.ts +++ b/packages/nodes-base/nodes/QuickBase/GenericFunctions.ts @@ -17,11 +17,15 @@ export async function quickbaseApiRequest(this: IExecuteFunctions | ILoadOptions const credentials = this.getCredentials('quickbaseApi') as IDataObject; - if (credentials.hostname === '') { + if (credentials === undefined) { + throw new Error('No credentials got returned!'); + } + + if (!credentials.hostname) { throw new Error('Hostname must be defined'); } - if (credentials.userKey === '') { + if (!credentials.userToken) { throw new Error('User Token must be defined'); } @@ -71,14 +75,14 @@ export async function quickbaseApiRequest(this: IExecuteFunctions | ILoadOptions export async function getFieldsObject(this: IHookFunctions | ILoadOptionsFunctions | IExecuteFunctions, tableId: string): any { const fieldsLabelKey: { [key: string]: number } = {}; const fieldsIdKey: { [key: number]: string } = {}; - const data = await quickbaseApiRequest.call(this, 'GET', '/fields', {}, { tableId }); + const data = await quickbaseApiRequest.call(this, 'GET', '/fields', {}, { tableId }); for (const field of data) { fieldsLabelKey[field.label] = field.id; fieldsIdKey[field.id] = field.label; } return { fieldsLabelKey, fieldsIdKey }; } - + export async function quickbaseApiRequestAllItems(this: IHookFunctions | ILoadOptionsFunctions | IExecuteFunctions, method: string, resource: string, body: any = {}, query: IDataObject = {}): Promise { // tslint:disable-line:no-any const returnData: IDataObject[] = []; @@ -125,7 +129,7 @@ export async function quickbaseApiRequestAllItems(this: IHookFunctions | ILoadOp returnData.push.apply(returnData, responseData); responseData = []; } while ( - returnData.length < metadata.totalRecords + returnData.length < metadata.totalRecords ); return returnData; diff --git a/packages/nodes-base/nodes/QuickBase/QuickBase.node.ts b/packages/nodes-base/nodes/QuickBase/QuickBase.node.ts index 4d7b94b4e4..c47cc05b2c 100644 --- a/packages/nodes-base/nodes/QuickBase/QuickBase.node.ts +++ b/packages/nodes-base/nodes/QuickBase/QuickBase.node.ts @@ -42,7 +42,7 @@ export class QuickBase implements INodeType { displayName: 'Quick Base', name: 'quickbase', icon: 'file:quickbase.png', - group: [ 'input' ], + group: ['input'], version: 1, subtitle: '={{$parameter["operation"] + ": " + $parameter["resource"]}}', description: 'Integrate with the Quick Base RESTful API.', @@ -50,11 +50,12 @@ export class QuickBase implements INodeType { name: 'Quick Base', color: '#73489d', }, - inputs: [ 'main' ], - outputs: [ 'main' ], + inputs: ['main'], + outputs: ['main'], credentials: [ { name: 'quickbaseApi', + required: true, }, ], properties: [ @@ -158,8 +159,8 @@ export class QuickBase implements INodeType { const limit = this.getNodeParameter('limit', i) as number; responseData = responseData.splice(0, limit); - } - + } + returnData.push.apply(returnData, responseData); } } @@ -176,7 +177,7 @@ export class QuickBase implements INodeType { const versionNumber = this.getNodeParameter('versionNumber', i) as string; - responseData = await quickbaseApiRequest.call(this,'DELETE', `/files/${tableId}/${recordId}/${fieldId}/${versionNumber}`); + responseData = await quickbaseApiRequest.call(this, 'DELETE', `/files/${tableId}/${recordId}/${fieldId}/${versionNumber}`); returnData.push(responseData); } @@ -210,20 +211,20 @@ export class QuickBase implements INodeType { const dataPropertyNameDownload = this.getNodeParameter('binaryPropertyName', i) as string; - responseData = await quickbaseApiRequest.call(this,'GET', `/files/${tableId}/${recordId}/${fieldId}/${versionNumber}`, {}, {}, { json: false, resolveWithFullResponse: true }); + responseData = await quickbaseApiRequest.call(this, 'GET', `/files/${tableId}/${recordId}/${fieldId}/${versionNumber}`, {}, {}, { json: false, resolveWithFullResponse: true }); //content-disposition': 'attachment; filename="dog-puppy-on-garden-royalty-free-image-1586966191.jpg"', const contentDisposition = responseData.headers['content-disposition']; const data = Buffer.from(responseData.body as string, 'base64'); - items[i].binary![dataPropertyNameDownload] = await this.helpers.prepareBinaryData(data as unknown as Buffer, contentDisposition.split('=')[1]); + items[i].binary![dataPropertyNameDownload] = await this.helpers.prepareBinaryData(data as unknown as Buffer, contentDisposition.split('=')[1]); } - + return this.prepareOutputData(items); } } - + if (resource === 'record') { if (operation === 'create') { const tableId = this.getNodeParameter('tableId', 0) as string; @@ -248,7 +249,7 @@ export class QuickBase implements INodeType { record[fieldsLabelKey[key].toString()] = { value: items[i].json[key] }; } } - + data.push(record); } @@ -269,7 +270,7 @@ export class QuickBase implements INodeType { if (simple === true) { const { data: records } = responseData; responseData = []; - + for (const record of records) { const data: IDataObject = {}; for (const [key, value] of Object.entries(record)) { @@ -285,7 +286,7 @@ export class QuickBase implements INodeType { returnData.push(responseData); } } - + if (operation === 'delete') { for (let i = 0; i < length; i++) { const tableId = this.getNodeParameter('tableId', i) as string; @@ -329,14 +330,14 @@ export class QuickBase implements INodeType { // body.groupBy = group; // delete body.groupByUi; // } - + if (returnAll) { responseData = await quickbaseApiRequestAllItems.call(this, 'POST', '/records/query', body, qs); } else { - body.options = { top: this.getNodeParameter('limit', i) as number }; + body.options = { top: this.getNodeParameter('limit', i) as number }; responseData = await quickbaseApiRequest.call(this, 'POST', '/records/query', body, qs); - + const { data: records, fields } = responseData; responseData = []; @@ -345,7 +346,7 @@ export class QuickBase implements INodeType { for (const field of fields) { fieldsIdKey[field.id] = field.label; } - + for (const record of records) { const data: IDataObject = {}; for (const [key, value] of Object.entries(record)) { @@ -389,7 +390,7 @@ export class QuickBase implements INodeType { } record[fieldsLabelKey['Record ID#']] = { value: items[i].json[updateKey] }; - + data.push(record); } @@ -410,7 +411,7 @@ export class QuickBase implements INodeType { if (simple === true) { const { data: records } = responseData; responseData = []; - + for (const record of records) { const data: IDataObject = {}; for (const [key, value] of Object.entries(record)) { @@ -460,7 +461,7 @@ export class QuickBase implements INodeType { } record[mergeFieldId] = { value: items[i].json[updateKey] }; - + data.push(record); } @@ -482,7 +483,7 @@ export class QuickBase implements INodeType { if (simple === true) { const { data: records } = responseData; responseData = []; - + for (const record of records) { const data: IDataObject = {}; for (const [key, value] of Object.entries(record)) { @@ -516,7 +517,7 @@ export class QuickBase implements INodeType { if (returnAll) { responseData = await quickbaseApiRequestAllItems.call(this, 'POST', `/reports/${reportId}/run`, {}, qs); } else { - qs.top = this.getNodeParameter('limit', i) as number; + qs.top = this.getNodeParameter('limit', i) as number; responseData = await quickbaseApiRequest.call(this, 'POST', `/reports/${reportId}/run`, {}, qs); @@ -528,7 +529,7 @@ export class QuickBase implements INodeType { for (const field of fields) { fieldsIdKey[field.id] = field.label; } - + for (const record of records) { const data: IDataObject = {}; for (const [key, value] of Object.entries(record)) { diff --git a/packages/nodes-base/nodes/QuickBase/RecordDescription.ts b/packages/nodes-base/nodes/QuickBase/RecordDescription.ts index e1f7a43e34..73614d9297 100644 --- a/packages/nodes-base/nodes/QuickBase/RecordDescription.ts +++ b/packages/nodes-base/nodes/QuickBase/RecordDescription.ts @@ -83,6 +83,7 @@ export const recordFields = [ }, }, default: '', + required: true, placeholder: 'id,name,description', description: 'Comma separated list of the properties which should used as columns for the new rows.', }, @@ -363,7 +364,7 @@ export const recordFields = [ name: 'where', type: 'string', default: '', - description: 'The filter, using the Quick Base query language, which determines the records to return.', + description: 'The filter, using the Quick Base query language, which determines the records to return.', }, ], }, @@ -403,6 +404,7 @@ export const recordFields = [ }, }, default: '', + required: true, placeholder: 'id,name,description', description: 'Comma separated list of the properties which should used as columns for the new rows.', }, @@ -520,6 +522,7 @@ export const recordFields = [ }, }, default: '', + required: true, placeholder: 'id,name,description', description: 'Comma separated list of the properties which should used as columns for the new rows.', }, diff --git a/packages/nodes-base/nodes/QuickBase/ReportDescription.ts b/packages/nodes-base/nodes/QuickBase/ReportDescription.ts index ab9f2f3a15..ea3406dc4e 100644 --- a/packages/nodes-base/nodes/QuickBase/ReportDescription.ts +++ b/packages/nodes-base/nodes/QuickBase/ReportDescription.ts @@ -51,7 +51,7 @@ export const reportFields = [ ], }, }, - description: 'The table identifier', + description: 'The table identifier.', }, { displayName: 'Report ID', @@ -69,7 +69,7 @@ export const reportFields = [ ], }, }, - description: 'The identifier of the report, unique to the table', + description: 'The identifier of the report, unique to the table.', }, /* -------------------------------------------------------------------------- */ /* report:run */ @@ -90,7 +90,7 @@ export const reportFields = [ ], }, }, - description: 'The table identifier', + description: 'The table identifier.', }, { displayName: 'Report ID', @@ -108,7 +108,7 @@ export const reportFields = [ ], }, }, - description: 'The identifier of the report, unique to the table', + description: 'The identifier of the report, unique to the table.', }, { displayName: 'Return All', diff --git a/packages/nodes-base/nodes/QuickBase/quickbase.png b/packages/nodes-base/nodes/QuickBase/quickbase.png index 0d362fd7e1571d53b9780906dec5022fe948ed03..e9d3708db31b276e900b5a3911bf5a22db16a55a 100644 GIT binary patch literal 1258 zcmeAS@N?(olHy`uVBq!ia0vp^HXzKw3=&b&bYNg$3=8lHaRqWqJmwa9&nxzvTjDXV z)N59e&&*=)g+Mk?9EeIiXXgjaE(LQ-Jr|UC%q{_v?jR|!?7UJS8;IQI0m)*ZGWU7K zKq)9Wx5R4>P`uO=ECn{C$PJ{W+%6$wX?~U4oR;AJDxc|P?sHm$CgylAD0iDu5k580 zXm_Q@%$C6ZH2W3tfy-+1JImZ=m$}YL^;=Sv)ZZ91!9n9xbw)4P??9h|y#@-Rc|b=3 zjVf}RU+lP`-hc9vcm-}?$flPB`2{olG1$kf$SF|y_3?IIwzrm=sxNPyTN>*i^5Dkq z6?5y$a-JR8zHw5!yOhL_JC|ln?Fn$v`S9%Ii32r7X-Osu|9)@Xw06<_mX^Hi)MP&u zX|BIluADl)YwLzJ6Fb{ltIDIJ!oA&GO!d@{@4l1Iz`%6J)5S5wB#e5RUWca8$%A)Uo*m{QB$+lpFqUU>iil8|fowl^QN-~ZhI^M~B)Q_sB&l8(fF z)ckkr=CpU=#~z-`==7?2{%>`Va`@iGx99txXW=xw^+bMRgfi!xBZ&>0rj_JcNY7O> zQ`*gaAfwDy#OO8?`~4(2r6N(S*A9}CXWqzeI#6Ne5fgcn<<#zMHPJ~QWkl6 zzd9ch{-0`rP zh0m<{%pb`kieFV2Q^ef)=4dDeb8Iu~ez%25(JV^+!4Yv&-T7keC30tv?OHukbkWXp z?In^1&loH|ZeDWM#w*k0{Gm;zUV>BqZg{Ql^UG@jOaCeXHg?f%2j9xC$*x-!UOPc~ zkFlWYQ8%5XJKdIkx_ye9Nxs0wSSWOxQj7Pt=0KriDU9knw=+&Ls>?IfkvZ9O{@K&j zOJ0TiI_iAx(&>a*3a+9PYC0mcG}i}8-eC(+li3;hcKthBFJZrsBP;jUhwt=ui$xp7MTkE9k+RJC$lMc}x}DM$vrGg|=<^ou-|^yj%f{-y z1C8bJW#<1Y`5Ely{a(eSx8>Bv*(ZDt-uXO-X-(`_&1HuC?>tV%EDqVDZt#`!!GouN z8M6&|JU_m^HRHhf;)c)0`l+Y+mEHc>*E4?0`y4ATG0h&BwHQ2I{an^LB{Ts5(r7%Q literal 5062 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