From 2c72584b55521b437baa20ddad7c919807fd9f8f Mon Sep 17 00:00:00 2001 From: pemontto <939704+pemontto@users.noreply.github.com> Date: Sat, 2 Apr 2022 16:22:13 +0100 Subject: [PATCH] feat(ServiceNow Node): Add basicAuth support and fix getColumns loadOptions (#2712) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * โœจ Support basic auth for ServiceNow * ๐Ÿ› Support ServiceNow sysparm_fields as string * :zap: credential test for basic auth * fix(Google Tasks Node): Fix "Show Completed" option and hide title field where not needed (#2741) * ๐Ÿ› Google Tasks: Fix showCompleted * :zap: Improvements Co-authored-by: ricardo * feat(Mocean Node): Add "Delivery Report URL" option and credential tests (#3075) * add dlr url column add dlr url(delivery report URl) column. Allow user set the endpoint to receive the report * update update delivery report url description * :zap: fixed nodelinter issues, added credential test, replaced icon * :zap: Improvements Co-authored-by: d3no Co-authored-by: Michael Kret * feat(Emelia Node): Add Campaign > Duplicate functionality (#3000) * feat(Emelia Node): Add campaign duplication feature * :zap: small ui fixes, added credential test, fixed nodelinter issues * :zap: Improvements * :zap: Updated wording for Number operations on IF-Node (#3065) * fix(Google Tasks Node): Fix "Show Completed" option and hide title field where not needed (#2741) * ๐Ÿ› Google Tasks: Fix showCompleted * :zap: Improvements Co-authored-by: ricardo * feat(Mocean Node): Add "Delivery Report URL" option and credential tests (#3075) * add dlr url column add dlr url(delivery report URl) column. Allow user set the endpoint to receive the report * update update delivery report url description * :zap: fixed nodelinter issues, added credential test, replaced icon * :zap: Improvements Co-authored-by: d3no Co-authored-by: Michael Kret * :zap: Normalize name Co-authored-by: Michael Kret Co-authored-by: ricardo Co-authored-by: Jonathan Bennetts Co-authored-by: Tom <19203795+that-one-tom@users.noreply.github.com> Co-authored-by: Ricardo Espinoza Co-authored-by: d3no Co-authored-by: Jan Oberhauser * :zap: fix nodelinter issues, added hint to field option * fix(GraphQL Node)!: Correctly report errors returned by the API (#3071) * upstream merge * :zap: graphql node will throw error when response has errors property * :hammer: updated changelog * :zap: Improvements * :zap: Improvements * :zap: Add package-lock.json back Co-authored-by: ricardo * feat(FTP Node): Add option to recursively create directories on rename (#3001) * Recursively Make Directories on SFTP Rename * Linting * :zap: Improvement * :zap: Rename "Move" to "Create Directories" * Change "Create Directories" description Co-authored-by: ricardo * feat(Microsoft Teams Node): Add chat message support (#2635) * โœจ Add chat messages to MS Teams node * Updated credentials to include missing scope * :zap: Small improvements Co-authored-by: Jonathan Bennetts Co-authored-by: ricardo * feat(Mautic Node): Add credential test and allow trailing slash in host (#3080) * Updated Mautic to stop trailing slashes from causing an issue * Fixed oauth failing when there is a trailing slash in the mautic host * Added credential test * test: Fix randomly failing UM tests (#3061) * :zap: Declutter test logs * :bug: Fix random passwords length * :bug: Fix password hashing in test user creation * :bug: Hash leftover password * :zap: Improve error message for `compare` * :zap: Restore `randomInvalidPassword` contant * :zap: Mock Telemetry module to prevent `--forceExit` * :zap: Silence logger * :zap: Simplify condition * :zap: Unhash password in payload * fix(NocoDB Node): Fix pagination (#3081) * feat(Strava Node): Add "Get Streams" operation (#2582) * Strava node: adding getStreams operation * Changed the keys to use multiOptions Co-authored-by: Jonathan Bennetts * :zap: Improvements * fix(core): Fix crash on webhook when last node did not return data * fix(Salesforce Node): Fix issue that "status" did not get used for Case => Create & Update (#2212) * bugfix for salesforce case create and update case not picking status * :bug: Fix issue with package-lock.json Co-authored-by: ricardo * :bug: Fix issue with credentials * :zap: Fix basicAuth * :zap: Reset default Co-authored-by: Michael Kret Co-authored-by: Tom <19203795+that-one-tom@users.noreply.github.com> Co-authored-by: ricardo Co-authored-by: Ricardo Espinoza Co-authored-by: d3no Co-authored-by: Charles Lecalier Co-authored-by: Jonathan Bennetts Co-authored-by: Jan Oberhauser Co-authored-by: Michael Kret <88898367+michael-radency@users.noreply.github.com> Co-authored-by: Rhys Williams Co-authored-by: Ivรกn Ovejero Co-authored-by: Luis Cipriani <37157+lfcipriani@users.noreply.github.com> Co-authored-by: Ketan Somvanshi --- .../ServiceNowBasicApi.credentials.ts | 35 +++++++++++ .../ServiceNowOAuth2Api.credentials.ts | 3 +- .../ServiceNow/BusinessServiceDescription.ts | 9 ++- .../ConfigurationItemsDescription.ts | 11 ++-- .../nodes/ServiceNow/DepartmentDescription.ts | 9 ++- .../nodes/ServiceNow/DictionaryDescription.ts | 9 ++- .../nodes/ServiceNow/GenericFunctions.ts | 20 ++++-- .../nodes/ServiceNow/IncidentDescription.ts | 49 +++++++++++---- .../nodes/ServiceNow/ServiceNow.node.ts | 63 +++++++++++++++---- .../ServiceNow/TableRecordDescription.ts | 19 +++--- .../nodes/ServiceNow/UserDescription.ts | 25 +++++--- .../nodes/ServiceNow/UserGroupDescription.ts | 8 ++- .../nodes/ServiceNow/UserRoleDescription.ts | 8 ++- packages/nodes-base/package.json | 1 + 14 files changed, 199 insertions(+), 70 deletions(-) create mode 100644 packages/nodes-base/credentials/ServiceNowBasicApi.credentials.ts diff --git a/packages/nodes-base/credentials/ServiceNowBasicApi.credentials.ts b/packages/nodes-base/credentials/ServiceNowBasicApi.credentials.ts new file mode 100644 index 0000000000..b55cbb7e73 --- /dev/null +++ b/packages/nodes-base/credentials/ServiceNowBasicApi.credentials.ts @@ -0,0 +1,35 @@ +import { + IAuthenticateBasicAuth, + ICredentialType, + INodeProperties, + ICredentialTestRequest, +} from 'n8n-workflow'; + +export class ServiceNowBasicApi implements ICredentialType { + name = 'serviceNowBasicApi'; + extends = [ + 'httpBasicAuth' + ]; + displayName = 'ServiceNow Basic Auth API'; + documentationUrl = 'serviceNow'; + properties: INodeProperties[] = [ + { + displayName: 'Subdomain', + name: 'subdomain', + type: 'string', + default: '', + hint: 'The subdomain can be extracted from the URL. If the URL is: https://dev99890.service-now.com the subdomain is dev99890', + required: true, + }, + ]; + authenticate: IAuthenticateBasicAuth = { + type: 'basicAuth', + properties: {}, + }; + test: ICredentialTestRequest = { + request: { + baseURL: '=https://{{$credentials?.subdomain}}.service-now.com', + url: '/api/now/table/sys_user_role', + } + } +} diff --git a/packages/nodes-base/credentials/ServiceNowOAuth2Api.credentials.ts b/packages/nodes-base/credentials/ServiceNowOAuth2Api.credentials.ts index 9539cb1fe1..4bd0bc2e19 100644 --- a/packages/nodes-base/credentials/ServiceNowOAuth2Api.credentials.ts +++ b/packages/nodes-base/credentials/ServiceNowOAuth2Api.credentials.ts @@ -16,8 +16,7 @@ export class ServiceNowOAuth2Api implements ICredentialType { name: 'subdomain', type: 'string', default: '', - placeholder: 'n8n', - description: 'The subdomain of your ServiceNow environment', + hint: 'The subdomain can be extracted from the URL. If the URL is: https://dev99890.service-now.com the subdomain is dev99890', required: true, }, { diff --git a/packages/nodes-base/nodes/ServiceNow/BusinessServiceDescription.ts b/packages/nodes-base/nodes/ServiceNow/BusinessServiceDescription.ts index c5fd6dd0fe..fddf24e3f9 100644 --- a/packages/nodes-base/nodes/ServiceNow/BusinessServiceDescription.ts +++ b/packages/nodes-base/nodes/ServiceNow/BusinessServiceDescription.ts @@ -7,6 +7,7 @@ export const businessServiceOperations: INodeProperties[] = [ displayName: 'Operation', name: 'operation', type: 'options', + noDataExpression: true, displayOptions: { show: { resource: [ @@ -44,7 +45,7 @@ export const businessServiceFields: INodeProperties[] = [ }, }, default: false, - description: 'If all results should be returned or only up to a given limit', + description: 'Whether to return all results or only up to a given limit', }, { displayName: 'Limit', @@ -99,17 +100,19 @@ export const businessServiceFields: INodeProperties[] = [ name: 'sysparm_fields', type: 'multiOptions', typeOptions: { + // nodelinter-ignore-next-line loadOptionsMethod: 'getColumns', }, - default: '', + default: [], description: 'A list of fields to return', + hint: 'String of comma separated values or an array of strings can be set in an expression', }, { displayName: 'Filter', name: 'sysparm_query', type: 'string', default: '', - description: 'An encoded query string used to filter the results. More info', + description: 'An encoded query string used to filter the results. More info.', }, { displayName: 'Return Values', diff --git a/packages/nodes-base/nodes/ServiceNow/ConfigurationItemsDescription.ts b/packages/nodes-base/nodes/ServiceNow/ConfigurationItemsDescription.ts index 1d3f738f08..33804b9601 100644 --- a/packages/nodes-base/nodes/ServiceNow/ConfigurationItemsDescription.ts +++ b/packages/nodes-base/nodes/ServiceNow/ConfigurationItemsDescription.ts @@ -7,6 +7,7 @@ export const configurationItemsOperations: INodeProperties[] = [ displayName: 'Operation', name: 'operation', type: 'options', + noDataExpression: true, displayOptions: { show: { resource: [ @@ -44,7 +45,7 @@ export const configurationItemsFields: INodeProperties[] = [ }, }, default: false, - description: 'If all results should be returned or only up to a given limit', + description: 'Whether to return all results or only up to a given limit', }, { displayName: 'Limit', @@ -68,7 +69,7 @@ export const configurationItemsFields: INodeProperties[] = [ maxValue: 500, }, default: 50, - description: 'The max number of results to return', + description: 'Max number of results to return', }, { displayName: 'Options', @@ -99,17 +100,19 @@ export const configurationItemsFields: INodeProperties[] = [ name: 'sysparm_fields', type: 'multiOptions', typeOptions: { + // nodelinter-ignore-next-line loadOptionsMethod: 'getColumns', }, - default: '', + default: [], description: 'A list of fields to return', + hint: 'String of comma separated values or an array of strings can be set in an expression', }, { displayName: 'Filter', name: 'sysparm_query', type: 'string', default: '', - description: 'An encoded query string used to filter the results. More info', + description: 'An encoded query string used to filter the results. More info.', }, { displayName: 'Return Values', diff --git a/packages/nodes-base/nodes/ServiceNow/DepartmentDescription.ts b/packages/nodes-base/nodes/ServiceNow/DepartmentDescription.ts index 28c3d93090..dcc6f950fb 100644 --- a/packages/nodes-base/nodes/ServiceNow/DepartmentDescription.ts +++ b/packages/nodes-base/nodes/ServiceNow/DepartmentDescription.ts @@ -7,6 +7,7 @@ export const departmentOperations: INodeProperties[] = [ displayName: 'Operation', name: 'operation', type: 'options', + noDataExpression: true, displayOptions: { show: { resource: [ @@ -44,7 +45,7 @@ export const departmentFields: INodeProperties[] = [ }, }, default: false, - description: 'If all results should be returned or only up to a given limit', + description: 'Whether to return all results or only up to a given limit', }, { displayName: 'Limit', @@ -99,17 +100,19 @@ export const departmentFields: INodeProperties[] = [ name: 'sysparm_fields', type: 'multiOptions', typeOptions: { + // nodelinter-ignore-next-line loadOptionsMethod: 'getColumns', }, - default: '', + default: [], description: 'A list of fields to return', + hint: 'String of comma separated values or an array of strings can be set in an expression', }, { displayName: 'Filter', name: 'sysparm_query', type: 'string', default: '', - description: 'An encoded query string used to filter the results. More info', + description: 'An encoded query string used to filter the results. More info.', }, { displayName: 'Return Values', diff --git a/packages/nodes-base/nodes/ServiceNow/DictionaryDescription.ts b/packages/nodes-base/nodes/ServiceNow/DictionaryDescription.ts index ba1152b31c..718a24cbf9 100644 --- a/packages/nodes-base/nodes/ServiceNow/DictionaryDescription.ts +++ b/packages/nodes-base/nodes/ServiceNow/DictionaryDescription.ts @@ -7,6 +7,7 @@ export const dictionaryOperations: INodeProperties[] = [ displayName: 'Operation', name: 'operation', type: 'options', + noDataExpression: true, displayOptions: { show: { resource: [ @@ -44,7 +45,7 @@ export const dictionaryFields: INodeProperties[] = [ }, }, default: false, - description: 'If all results should be returned or only up to a given limit', + description: 'Whether to return all results or only up to a given limit', }, { displayName: 'Limit', @@ -99,17 +100,19 @@ export const dictionaryFields: INodeProperties[] = [ name: 'sysparm_fields', type: 'multiOptions', typeOptions: { + // nodelinter-ignore-next-line loadOptionsMethod: 'getColumns', }, - default: '', + default: [], description: 'A list of fields to return', + hint: 'String of comma separated values or an array of strings can be set in an expression', }, { displayName: 'Filter', name: 'sysparm_query', type: 'string', default: '', - description: 'An encoded query string used to filter the results. More info', + description: 'An encoded query string used to filter the results. More info.', }, { displayName: 'Return Values', diff --git a/packages/nodes-base/nodes/ServiceNow/GenericFunctions.ts b/packages/nodes-base/nodes/ServiceNow/GenericFunctions.ts index 2924cdf53d..5d121933f0 100644 --- a/packages/nodes-base/nodes/ServiceNow/GenericFunctions.ts +++ b/packages/nodes-base/nodes/ServiceNow/GenericFunctions.ts @@ -10,15 +10,25 @@ import { import { IDataObject, INodePropertyOptions, + JsonObject, NodeApiError, } from 'n8n-workflow'; export async function serviceNowApiRequest(this: IExecuteFunctions | ILoadOptionsFunctions, method: string, resource: string, body: any = {}, qs: IDataObject = {}, uri?: string, option: IDataObject = {}): Promise { // tslint:disable-line:no-any - const credentials = await this.getCredentials('serviceNowOAuth2Api'); + const headers = {} as IDataObject; + const authenticationMethod = this.getNodeParameter('authentication', 0, 'oAuth2') as string; + + let credentials; + + if (authenticationMethod === 'basicAuth') { + credentials = await this.getCredentials('serviceNowBasicApi'); + } else { + credentials = await this.getCredentials('serviceNowOAuth2Api'); + } const options: OptionsWithUri = { - headers: {}, + headers, method, qs, body, @@ -38,11 +48,11 @@ export async function serviceNowApiRequest(this: IExecuteFunctions | ILoadOption } try { - - return await this.helpers.requestOAuth2!.call(this, 'serviceNowOAuth2Api', options); + const credentialType = authenticationMethod === 'oAuth2' ? 'serviceNowOAuth2Api' : 'serviceNowBasicApi'; + return await this.helpers.requestWithAuthentication.call(this, credentialType, options); } catch (error) { - throw new NodeApiError(this.getNode(), error); + throw new NodeApiError(this.getNode(), (error as JsonObject)); } } diff --git a/packages/nodes-base/nodes/ServiceNow/IncidentDescription.ts b/packages/nodes-base/nodes/ServiceNow/IncidentDescription.ts index ba06f0d45e..744ee35472 100644 --- a/packages/nodes-base/nodes/ServiceNow/IncidentDescription.ts +++ b/packages/nodes-base/nodes/ServiceNow/IncidentDescription.ts @@ -7,6 +7,7 @@ export const incidentOperations: INodeProperties[] = [ displayName: 'Operation', name: 'operation', type: 'options', + noDataExpression: true, displayOptions: { show: { resource: [ @@ -85,19 +86,21 @@ export const incidentFields: INodeProperties[] = [ name: 'assigned_to', type: 'options', typeOptions: { + // nodelinter-ignore-next-line loadOptionsMethod: 'getUsers', loadOptionsDependsOn: [ 'additionalFields.assignment_group', ], }, default: '', - description: 'Which user is the incident assigned to. Requires the selection of an assignment group', + description: 'Which user is the incident assigned to. Requires the selection of an assignment group.', }, { displayName: 'Assignment Group', name: 'assignment_group', type: 'options', typeOptions: { + // nodelinter-ignore-next-line loadOptionsMethod: 'getAssignmentGroups', }, default: '', @@ -108,6 +111,7 @@ export const incidentFields: INodeProperties[] = [ name: 'business_service', type: 'options', typeOptions: { + // nodelinter-ignore-next-line loadOptionsMethod: 'getBusinessServices', }, default: '', @@ -125,6 +129,7 @@ export const incidentFields: INodeProperties[] = [ name: 'category', type: 'options', typeOptions: { + // nodelinter-ignore-next-line loadOptionsMethod: 'getIncidentCategories', }, default: '', @@ -142,9 +147,10 @@ export const incidentFields: INodeProperties[] = [ name: 'cmdb_ci', type: 'multiOptions', typeOptions: { + // nodelinter-ignore-next-line loadOptionsMethod: 'getConfigurationItems', }, - default: '', + default: [], description: 'Configuration Items, \'cmdb_ci\' in metadata', }, { @@ -197,7 +203,7 @@ export const incidentFields: INodeProperties[] = [ value: 1, }, ], - default: '', + default: 1, description: 'The impact of the incident', }, { @@ -205,16 +211,18 @@ export const incidentFields: INodeProperties[] = [ name: 'close_code', type: 'options', typeOptions: { + // nodelinter-ignore-next-line loadOptionsMethod: 'getIncidentResolutionCodes', }, default: '', - description: 'The resolution code of the incident. \'close_code\' in metadata', + description: 'The resolution code of the incident, \'close_code\' in metadata', }, { displayName: 'State', name: 'state', type: 'options', typeOptions: { + // nodelinter-ignore-next-line loadOptionsMethod: 'getIncidentStates', }, default: '', @@ -225,6 +233,7 @@ export const incidentFields: INodeProperties[] = [ name: 'subcategory', type: 'options', typeOptions: { + // nodelinter-ignore-next-line loadOptionsMethod: 'getIncidentSubcategories', loadOptionsDependsOn: [ 'additionalFields.category', @@ -251,7 +260,7 @@ export const incidentFields: INodeProperties[] = [ value: 1, }, ], - default: '', + default: 1, description: 'The urgency of the incident', }, ], @@ -275,7 +284,7 @@ export const incidentFields: INodeProperties[] = [ }, }, default: false, - description: 'If all results should be returned or only up to a given limit', + description: 'Whether to return all results or only up to a given limit', }, { displayName: 'Limit', @@ -330,17 +339,19 @@ export const incidentFields: INodeProperties[] = [ name: 'sysparm_fields', type: 'multiOptions', typeOptions: { + // nodelinter-ignore-next-line loadOptionsMethod: 'getColumns', }, - default: '', + default: [], description: 'A list of fields to return', + hint: 'String of comma separated values or an array of strings can be set in an expression', }, { displayName: 'Filter', name: 'sysparm_query', type: 'string', default: '', - description: 'An encoded query string used to filter the results. More info', + description: 'An encoded query string used to filter the results. More info.', }, { displayName: 'Return Values', @@ -417,10 +428,12 @@ export const incidentFields: INodeProperties[] = [ name: 'sysparm_fields', type: 'multiOptions', typeOptions: { + // nodelinter-ignore-next-line loadOptionsMethod: 'getColumns', }, - default: '', + default: [], description: 'A list of fields to return', + hint: 'String of comma separated values or an array of strings can be set in an expression', }, { displayName: 'Return Values', @@ -489,19 +502,21 @@ export const incidentFields: INodeProperties[] = [ name: 'assigned_to', type: 'options', typeOptions: { + // nodelinter-ignore-next-line loadOptionsMethod: 'getUsers', loadOptionsDependsOn: [ 'additionalFields.assignment_group', ], }, default: '', - description: 'Which user is the incident assigned to. Requires the selection of an assignment group', + description: 'Which user is the incident assigned to. Requires the selection of an assignment group.', }, { displayName: 'Assignment Group', name: 'assignment_group', type: 'options', typeOptions: { + // nodelinter-ignore-next-line loadOptionsMethod: 'getAssignmentGroups', }, default: '', @@ -512,6 +527,7 @@ export const incidentFields: INodeProperties[] = [ name: 'business_service', type: 'options', typeOptions: { + // nodelinter-ignore-next-line loadOptionsMethod: 'getBusinessServices', }, default: '', @@ -529,6 +545,7 @@ export const incidentFields: INodeProperties[] = [ name: 'category', type: 'options', typeOptions: { + // nodelinter-ignore-next-line loadOptionsMethod: 'getIncidentCategories', }, default: '', @@ -546,9 +563,10 @@ export const incidentFields: INodeProperties[] = [ name: 'cmdb_ci', type: 'multiOptions', typeOptions: { + // nodelinter-ignore-next-line loadOptionsMethod: 'getConfigurationItems', }, - default: '', + default: [], description: 'Configuration Items, \'cmdb_ci\' in metadata', }, { @@ -601,7 +619,7 @@ export const incidentFields: INodeProperties[] = [ value: 1, }, ], - default: '', + default: 1, description: 'The impact of the incident', }, { @@ -609,9 +627,11 @@ export const incidentFields: INodeProperties[] = [ name: 'close_code', type: 'options', typeOptions: { + // nodelinter-ignore-next-line loadOptionsMethod: 'getIncidentResolutionCodes', }, default: '', + // nodelinter-ignore-next-line description: 'The resolution code of the incident. \'close_code\' in metadata', }, { @@ -619,6 +639,7 @@ export const incidentFields: INodeProperties[] = [ name: 'hold_reason', type: 'options', typeOptions: { + // nodelinter-ignore-next-line loadOptionsMethod: 'getIncidentHoldReasons', }, default: '', @@ -629,6 +650,7 @@ export const incidentFields: INodeProperties[] = [ name: 'state', type: 'options', typeOptions: { + // nodelinter-ignore-next-line loadOptionsMethod: 'getIncidentStates', }, default: '', @@ -639,6 +661,7 @@ export const incidentFields: INodeProperties[] = [ name: 'subcategory', type: 'options', typeOptions: { + // nodelinter-ignore-next-line loadOptionsMethod: 'getIncidentSubcategories', loadOptionsDependsOn: [ 'additionalFields.category', @@ -665,7 +688,7 @@ export const incidentFields: INodeProperties[] = [ value: 1, }, ], - default: '', + default: 1, description: 'The urgency of the incident', }, ], diff --git a/packages/nodes-base/nodes/ServiceNow/ServiceNow.node.ts b/packages/nodes-base/nodes/ServiceNow/ServiceNow.node.ts index 98ad4bf4b4..d68afb18a3 100644 --- a/packages/nodes-base/nodes/ServiceNow/ServiceNow.node.ts +++ b/packages/nodes-base/nodes/ServiceNow/ServiceNow.node.ts @@ -9,6 +9,7 @@ import { INodePropertyOptions, INodeType, INodeTypeDescription, + JsonObject, NodeOperationError, } from 'n8n-workflow'; @@ -82,13 +83,49 @@ export class ServiceNow implements INodeType { { name: 'serviceNowOAuth2Api', required: true, + displayOptions: { + show: { + authentication: [ + 'oAuth2', + ], + }, + }, + }, + { + name: 'serviceNowBasicApi', + required: true, + displayOptions: { + show: { + authentication: [ + 'basicAuth', + ], + }, + }, }, ], properties: [ + { + displayName: 'Authentication', + name: 'authentication', + type: 'options', + options: [ + { + name: 'Basic Auth', + value: 'basicAuth', + }, + { + name: 'OAuth2', + value: 'oAuth2', + }, + ], + default: 'oAuth2', + description: 'Authentication method to use', + }, { displayName: 'Resource', name: 'resource', type: 'options', + noDataExpression: true, options: [ { name: 'Business Service', @@ -427,7 +464,7 @@ export class ServiceNow implements INodeType { const returnAll = this.getNodeParameter('returnAll', i) as boolean; qs = this.getNodeParameter('options', i) as IDataObject; - if (qs.sysparm_fields) { + if (qs.sysparm_fields && typeof qs.sysparm_fields !== 'string') { qs.sysparm_fields = (qs.sysparm_fields as string[]).join(','); } @@ -448,7 +485,7 @@ export class ServiceNow implements INodeType { const returnAll = this.getNodeParameter('returnAll', i) as boolean; qs = this.getNodeParameter('options', i) as IDataObject; - if (qs.sysparm_fields) { + if (qs.sysparm_fields && typeof qs.sysparm_fields !== 'string') { qs.sysparm_fields = (qs.sysparm_fields as string[]).join(','); } @@ -469,7 +506,7 @@ export class ServiceNow implements INodeType { const returnAll = this.getNodeParameter('returnAll', i) as boolean; qs = this.getNodeParameter('options', i) as IDataObject; - if (qs.sysparm_fields) { + if (qs.sysparm_fields && typeof qs.sysparm_fields !== 'string') { qs.sysparm_fields = (qs.sysparm_fields as string[]).join(','); } @@ -490,7 +527,7 @@ export class ServiceNow implements INodeType { const returnAll = this.getNodeParameter('returnAll', i) as boolean; qs = this.getNodeParameter('options', i) as IDataObject; - if (qs.sysparm_fields) { + if (qs.sysparm_fields && typeof qs.sysparm_fields !== 'string') { qs.sysparm_fields = (qs.sysparm_fields as string[]).join(','); } @@ -529,7 +566,7 @@ export class ServiceNow implements INodeType { const id = this.getNodeParameter('id', i) as string; qs = this.getNodeParameter('options', i) as IDataObject; - if (qs.sysparm_fields) { + if (qs.sysparm_fields && typeof qs.sysparm_fields !== 'string') { qs.sysparm_fields = (qs.sysparm_fields as string[]).join(','); } @@ -541,7 +578,7 @@ export class ServiceNow implements INodeType { const returnAll = this.getNodeParameter('returnAll', i) as boolean; qs = this.getNodeParameter('options', i) as IDataObject; - if (qs.sysparm_fields) { + if (qs.sysparm_fields && typeof qs.sysparm_fields !== 'string') { qs.sysparm_fields = (qs.sysparm_fields as string[]).join(','); } @@ -604,7 +641,7 @@ export class ServiceNow implements INodeType { const id = this.getNodeParameter('id', i) as string; qs = this.getNodeParameter('options', i) as IDataObject; - if (qs.sysparm_fields) { + if (qs.sysparm_fields && typeof qs.sysparm_fields !== 'string') { qs.sysparm_fields = (qs.sysparm_fields as string[]).join(','); } @@ -617,7 +654,7 @@ export class ServiceNow implements INodeType { const returnAll = this.getNodeParameter('returnAll', i) as boolean; qs = this.getNodeParameter('options', i) as IDataObject; - if (qs.sysparm_fields) { + if (qs.sysparm_fields && typeof qs.sysparm_fields !== 'string') { qs.sysparm_fields = (qs.sysparm_fields as string[]).join(','); } @@ -679,7 +716,7 @@ export class ServiceNow implements INodeType { const getOption = this.getNodeParameter('getOption', i) as string; qs = this.getNodeParameter('options', i) as IDataObject; - if (qs.sysparm_fields) { + if (qs.sysparm_fields && typeof qs.sysparm_fields !== 'string') { qs.sysparm_fields = (qs.sysparm_fields as string[]).join(','); } @@ -700,7 +737,7 @@ export class ServiceNow implements INodeType { const returnAll = this.getNodeParameter('returnAll', i) as boolean; qs = this.getNodeParameter('options', i) as IDataObject; - if (qs.sysparm_fields) { + if (qs.sysparm_fields && typeof qs.sysparm_fields !== 'string') { qs.sysparm_fields = (qs.sysparm_fields as string[]).join(','); } @@ -730,7 +767,7 @@ export class ServiceNow implements INodeType { const returnAll = this.getNodeParameter('returnAll', i) as boolean; qs = this.getNodeParameter('options', i) as IDataObject; - if (qs.sysparm_fields) { + if (qs.sysparm_fields && typeof qs.sysparm_fields !== 'string') { qs.sysparm_fields = (qs.sysparm_fields as string[]).join(','); } @@ -751,7 +788,7 @@ export class ServiceNow implements INodeType { const returnAll = this.getNodeParameter('returnAll', i) as boolean; qs = this.getNodeParameter('options', i) as IDataObject; - if (qs.sysparm_fields) { + if (qs.sysparm_fields && typeof qs.sysparm_fields !== 'string') { qs.sysparm_fields = (qs.sysparm_fields as string[]).join(','); } @@ -771,7 +808,7 @@ export class ServiceNow implements INodeType { } } catch (error) { if (this.continueOnFail()) { - returnData.push({ error: error.message }); + returnData.push({ error: (error as JsonObject).message }); continue; } diff --git a/packages/nodes-base/nodes/ServiceNow/TableRecordDescription.ts b/packages/nodes-base/nodes/ServiceNow/TableRecordDescription.ts index 9c60fbc511..a48cb47259 100644 --- a/packages/nodes-base/nodes/ServiceNow/TableRecordDescription.ts +++ b/packages/nodes-base/nodes/ServiceNow/TableRecordDescription.ts @@ -7,6 +7,7 @@ export const tableRecordOperations: INodeProperties[] = [ displayName: 'Operation', name: 'operation', type: 'options', + noDataExpression: true, displayOptions: { show: { resource: [ @@ -71,7 +72,7 @@ export const tableRecordFields: INodeProperties[] = [ type: 'options', options: [ { - name: 'Auto-map Input Data to Columns', + name: 'Auto-Map Input Data to Columns', value: 'mapInput', description: 'Use when node input names match destination field names', }, @@ -117,7 +118,7 @@ export const tableRecordFields: INodeProperties[] = [ }, default: '', required: false, - description: 'List of input properties to avoid sending, separated by commas. Leave empty to send all inputs', + description: 'List of input properties to avoid sending, separated by commas. Leave empty to send all inputs.', }, { displayName: 'Fields to Send', @@ -208,7 +209,7 @@ export const tableRecordFields: INodeProperties[] = [ }, }, default: false, - description: 'If all results should be returned or only up to a given limit', + description: 'Whether to return all results or only up to a given limit', }, { displayName: 'Limit', @@ -268,15 +269,16 @@ export const tableRecordFields: INodeProperties[] = [ 'tableName', ], }, - default: '', + default: [], description: 'A list of fields to return', + hint: 'String of comma separated values or an array of strings can be set in an expression', }, { displayName: 'Filter', name: 'sysparm_query', type: 'string', default: '', - description: 'An encoded query string used to filter the results. More info', + description: 'An encoded query string used to filter the results. More info.', }, { displayName: 'Return Values', @@ -380,8 +382,9 @@ export const tableRecordFields: INodeProperties[] = [ 'tableName', ], }, - default: '', + default: [], description: 'A list of fields to return', + hint: 'String of comma separated values or an array of strings can be set in an expression', }, { displayName: 'Return Values', @@ -455,7 +458,7 @@ export const tableRecordFields: INodeProperties[] = [ type: 'options', options: [ { - name: 'Auto-map Input Data to Columns', + name: 'Auto-Map Input Data to Columns', value: 'mapInput', description: 'Use when node input names match destination field names', }, @@ -501,7 +504,7 @@ export const tableRecordFields: INodeProperties[] = [ }, default: '', required: false, - description: 'List of input properties to avoid sending, separated by commas. Leave empty to send all inputs', + description: 'List of input properties to avoid sending, separated by commas. Leave empty to send all inputs.', }, { displayName: 'Fields to Send', diff --git a/packages/nodes-base/nodes/ServiceNow/UserDescription.ts b/packages/nodes-base/nodes/ServiceNow/UserDescription.ts index ca76b3c4b4..7a26f845b3 100644 --- a/packages/nodes-base/nodes/ServiceNow/UserDescription.ts +++ b/packages/nodes-base/nodes/ServiceNow/UserDescription.ts @@ -7,6 +7,7 @@ export const userOperations: INodeProperties[] = [ displayName: 'Operation', name: 'operation', type: 'options', + noDataExpression: true, displayOptions: { show: { resource: [ @@ -84,7 +85,7 @@ export const userFields: INodeProperties[] = [ displayName: 'Active', name: 'active', type: 'boolean', - default: '', + default: false, description: 'Whether to activate the user', }, { @@ -196,7 +197,7 @@ export const userFields: INodeProperties[] = [ displayName: 'Password Needs Reset', name: 'password_needs_reset', type: 'boolean', - default: '', + default: false, description: 'Whether to require a password reset when the user logs in', }, { @@ -213,7 +214,7 @@ export const userFields: INodeProperties[] = [ typeOptions: { loadOptionsMethod: 'getUserRoles', }, - default: '', + default: [], description: 'Roles of the user', }, { @@ -242,6 +243,7 @@ export const userFields: INodeProperties[] = [ name: 'user_name', type: 'string', default: '', + // nodelinter-ignore-next-line description: 'A username associated with the user (e.g. user_name.123)', }, { @@ -272,7 +274,7 @@ export const userFields: INodeProperties[] = [ }, }, default: false, - description: 'If all results should be returned or only up to a given limit', + description: 'Whether to return all results or only up to a given limit', }, { displayName: 'Limit', @@ -332,15 +334,16 @@ export const userFields: INodeProperties[] = [ 'operation', ], }, - default: '', + default: [], description: 'A list of fields to return', + hint: 'String of comma separated values or an array of strings can be set in an expression', }, { displayName: 'Filter', name: 'sysparm_query', type: 'string', default: '', - description: 'An encoded query string used to filter the results. More info', + description: 'An encoded query string used to filter the results. More info.', }, { displayName: 'Return Values', @@ -491,8 +494,9 @@ export const userFields: INodeProperties[] = [ 'operation', ], }, - default: '', + default: [], description: 'A list of fields to return', + hint: 'String of comma separated values or an array of strings can be set in an expression', }, { displayName: 'Return Values', @@ -560,7 +564,7 @@ export const userFields: INodeProperties[] = [ displayName: 'Active', name: 'active', type: 'boolean', - default: '', + default: false, description: 'Whether to activate the user', }, { @@ -672,7 +676,7 @@ export const userFields: INodeProperties[] = [ displayName: 'Password Needs Reset', name: 'password_needs_reset', type: 'boolean', - default: '', + default: false, description: 'Whether to require a password reset when the user logs in', }, { @@ -689,7 +693,7 @@ export const userFields: INodeProperties[] = [ typeOptions: { loadOptionsMethod: 'getUserRoles', }, - default: '', + default: [], description: 'Roles of the user', }, { @@ -718,6 +722,7 @@ export const userFields: INodeProperties[] = [ name: 'user_name', type: 'string', default: '', + // nodelinter-ignore-next-line description: 'A username associated with the user (e.g. user_name.123)', }, { diff --git a/packages/nodes-base/nodes/ServiceNow/UserGroupDescription.ts b/packages/nodes-base/nodes/ServiceNow/UserGroupDescription.ts index 271e7ea76d..a631c49905 100644 --- a/packages/nodes-base/nodes/ServiceNow/UserGroupDescription.ts +++ b/packages/nodes-base/nodes/ServiceNow/UserGroupDescription.ts @@ -7,6 +7,7 @@ export const userGroupOperations: INodeProperties[] = [ displayName: 'Operation', name: 'operation', type: 'options', + noDataExpression: true, displayOptions: { show: { resource: [ @@ -44,7 +45,7 @@ export const userGroupFields: INodeProperties[] = [ }, }, default: false, - description: 'If all results should be returned or only up to a given limit', + description: 'Whether to return all results or only up to a given limit', }, { displayName: 'Limit', @@ -101,15 +102,16 @@ export const userGroupFields: INodeProperties[] = [ typeOptions: { loadOptionsMethod: 'getColumns', }, - default: '', + default: [], description: 'A list of fields to return', + hint: 'String of comma separated values or an array of strings can be set in an expression', }, { displayName: 'Filter', name: 'sysparm_query', type: 'string', default: '', - description: 'An encoded query string used to filter the results. More info', + description: 'An encoded query string used to filter the results. More info.', }, { displayName: 'Return Values', diff --git a/packages/nodes-base/nodes/ServiceNow/UserRoleDescription.ts b/packages/nodes-base/nodes/ServiceNow/UserRoleDescription.ts index 59bb84f4fa..ba43b0d4af 100644 --- a/packages/nodes-base/nodes/ServiceNow/UserRoleDescription.ts +++ b/packages/nodes-base/nodes/ServiceNow/UserRoleDescription.ts @@ -7,6 +7,7 @@ export const userRoleOperations: INodeProperties[] = [ displayName: 'Operation', name: 'operation', type: 'options', + noDataExpression: true, displayOptions: { show: { resource: [ @@ -44,7 +45,7 @@ export const userRoleFields: INodeProperties[] = [ }, }, default: false, - description: 'If all results should be returned or only up to a given limit', + description: 'Whether to return all results or only up to a given limit', }, { displayName: 'Limit', @@ -101,15 +102,16 @@ export const userRoleFields: INodeProperties[] = [ typeOptions: { loadOptionsMethod: 'getColumns', }, - default: '', + default: [], description: 'A list of fields to return', + hint: 'String of comma separated values or an array of strings can be set in an expression', }, { displayName: 'Filter', name: 'sysparm_query', type: 'string', default: '', - description: 'An encoded query string used to filter the results. More info', + description: 'An encoded query string used to filter the results. More info.', }, { displayName: 'Return Values', diff --git a/packages/nodes-base/package.json b/packages/nodes-base/package.json index 43ab38c5fa..0374378b30 100644 --- a/packages/nodes-base/package.json +++ b/packages/nodes-base/package.json @@ -258,6 +258,7 @@ "dist/credentials/SentryIoOAuth2Api.credentials.js", "dist/credentials/SentryIoServerApi.credentials.js", "dist/credentials/ServiceNowOAuth2Api.credentials.js", + "dist/credentials/ServiceNowBasicApi.credentials.js", "dist/credentials/Sftp.credentials.js", "dist/credentials/ShopifyApi.credentials.js", "dist/credentials/Signl4Api.credentials.js",