mirror of
https://github.com/n8n-io/n8n.git
synced 2025-03-05 20:50:17 -08:00
Merge branch 'master' of https://github.com/n8n-io/n8n
This commit is contained in:
commit
9559a8929b
|
@ -555,7 +555,7 @@ class App {
|
||||||
this.app.get('/rest/node-parameter-options', ResponseHelper.send(async (req: express.Request, res: express.Response): Promise<INodePropertyOptions[]> => {
|
this.app.get('/rest/node-parameter-options', ResponseHelper.send(async (req: express.Request, res: express.Response): Promise<INodePropertyOptions[]> => {
|
||||||
const nodeType = req.query.nodeType as string;
|
const nodeType = req.query.nodeType as string;
|
||||||
let credentials: INodeCredentials | undefined = undefined;
|
let credentials: INodeCredentials | undefined = undefined;
|
||||||
const currentNodeParameters = req.query.currentNodeParameters as INodeParameters[];
|
const currentNodeParameters = JSON.parse('' + req.query.currentNodeParameters) as INodeParameters;
|
||||||
if (req.query.credentials !== undefined) {
|
if (req.query.credentials !== undefined) {
|
||||||
credentials = JSON.parse(req.query.credentials as string);
|
credentials = JSON.parse(req.query.credentials as string);
|
||||||
}
|
}
|
||||||
|
|
|
@ -387,10 +387,10 @@ export async function executeWorkflow(workflowInfo: IExecuteWorkflowInfo, additi
|
||||||
*
|
*
|
||||||
* @export
|
* @export
|
||||||
* @param {IWorkflowCredentials} credentials
|
* @param {IWorkflowCredentials} credentials
|
||||||
* @param {INodeParameters[]} [currentNodeParameters=[]]
|
* @param {INodeParameters} currentNodeParameters
|
||||||
* @returns {Promise<IWorkflowExecuteAdditionalData>}
|
* @returns {Promise<IWorkflowExecuteAdditionalData>}
|
||||||
*/
|
*/
|
||||||
export async function getBase(credentials: IWorkflowCredentials, currentNodeParameters: INodeParameters[] = []): Promise<IWorkflowExecuteAdditionalData> {
|
export async function getBase(credentials: IWorkflowCredentials, currentNodeParameters?: INodeParameters): Promise<IWorkflowExecuteAdditionalData> {
|
||||||
const urlBaseWebhook = WebhookHelpers.getWebhookBaseUrl();
|
const urlBaseWebhook = WebhookHelpers.getWebhookBaseUrl();
|
||||||
|
|
||||||
const timezone = config.get('generic.timezone') as string;
|
const timezone = config.get('generic.timezone') as string;
|
||||||
|
|
|
@ -152,7 +152,7 @@ export function getCredentials(workflow: Workflow, node: INode, type: string, ad
|
||||||
throw new Error(`Node type "${node.type}" does not have any credentials of type "${type}" defined!`);
|
throw new Error(`Node type "${node.type}" does not have any credentials of type "${type}" defined!`);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (NodeHelpers.displayParameter(node.parameters, nodeCredentialDescription, node.parameters) === false) {
|
if (NodeHelpers.displayParameter(additionalData.currentNodeParameters || node.parameters, nodeCredentialDescription, node.parameters) === false) {
|
||||||
// Credentials should not be displayed so return undefined even if they would be defined
|
// Credentials should not be displayed so return undefined even if they would be defined
|
||||||
return undefined;
|
return undefined;
|
||||||
}
|
}
|
||||||
|
@ -666,14 +666,14 @@ export function getLoadOptionsFunctions(workflow: Workflow, node: INode, additio
|
||||||
return getCredentials(workflow, node, type, additionalData);
|
return getCredentials(workflow, node, type, additionalData);
|
||||||
},
|
},
|
||||||
getCurrentNodeParameter: (parameterName: string): NodeParameterValue | INodeParameters | NodeParameterValue[] | INodeParameters[] | object | undefined => {
|
getCurrentNodeParameter: (parameterName: string): NodeParameterValue | INodeParameters | NodeParameterValue[] | INodeParameters[] | object | undefined => {
|
||||||
const nodeParameters = JSON.parse('' + additionalData.currentNodeParameters);
|
const nodeParameters = additionalData.currentNodeParameters;
|
||||||
if (nodeParameters && nodeParameters[parameterName]) {
|
if (nodeParameters && nodeParameters[parameterName]) {
|
||||||
return nodeParameters[parameterName];
|
return nodeParameters[parameterName];
|
||||||
}
|
}
|
||||||
return undefined;
|
return undefined;
|
||||||
},
|
},
|
||||||
getCurrentNodeParameters: (): INodeParameters | undefined => {
|
getCurrentNodeParameters: (): INodeParameters | undefined => {
|
||||||
return JSON.parse('' + additionalData.currentNodeParameters);
|
return additionalData.currentNodeParameters;
|
||||||
},
|
},
|
||||||
getNode: () => {
|
getNode: () => {
|
||||||
return getNode(node);
|
return getNode(node);
|
||||||
|
|
|
@ -504,11 +504,11 @@ export default mixins(
|
||||||
} else if (entry.finished === true) {
|
} else if (entry.finished === true) {
|
||||||
return 'The worklow execution was successful.';
|
return 'The worklow execution was successful.';
|
||||||
} else if (entry.retryOf !== undefined) {
|
} else if (entry.retryOf !== undefined) {
|
||||||
return `The workflow execution was a retry of "${entry.retryOf}" and did fail.<br />New retries have to be started from the original execution.`;
|
return `The workflow execution was a retry of "${entry.retryOf}" and failed.<br />New retries have to be started from the original execution.`;
|
||||||
} else if (entry.retrySuccessId !== undefined) {
|
} else if (entry.retrySuccessId !== undefined) {
|
||||||
return `The workflow execution did fail but the retry "${entry.retrySuccessId}" was successful.`;
|
return `The workflow execution failed but the retry "${entry.retrySuccessId}" was successful.`;
|
||||||
} else {
|
} else {
|
||||||
return 'The workflow execution did fail.';
|
return 'The workflow execution failed.';
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
async stopExecution (activeExecutionId: string) {
|
async stopExecution (activeExecutionId: string) {
|
||||||
|
|
|
@ -129,6 +129,10 @@ export default mixins(nodeBase, workflowHelpers).extend({
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
nodeSubtitle (): string | undefined {
|
nodeSubtitle (): string | undefined {
|
||||||
|
if (this.data.notesInFlow) {
|
||||||
|
return this.data.notes;
|
||||||
|
}
|
||||||
|
|
||||||
if (this.nodeType !== null && this.nodeType.subtitle !== undefined) {
|
if (this.nodeType !== null && this.nodeType.subtitle !== undefined) {
|
||||||
return this.workflow.getSimpleParameterValue(this.data as INode, this.nodeType.subtitle) as string | undefined;
|
return this.workflow.getSimpleParameterValue(this.data as INode, this.nodeType.subtitle) as string | undefined;
|
||||||
}
|
}
|
||||||
|
|
|
@ -142,6 +142,7 @@ export default mixins(
|
||||||
nodeValues: {
|
nodeValues: {
|
||||||
color: '#ff0000',
|
color: '#ff0000',
|
||||||
alwaysOutputData: false,
|
alwaysOutputData: false,
|
||||||
|
notesInFlow: false,
|
||||||
continueOnFail: false,
|
continueOnFail: false,
|
||||||
retryOnFail: false,
|
retryOnFail: false,
|
||||||
maxTries: 3,
|
maxTries: 3,
|
||||||
|
@ -162,6 +163,14 @@ export default mixins(
|
||||||
noDataExpression: true,
|
noDataExpression: true,
|
||||||
description: 'Notes to save with the node.',
|
description: 'Notes to save with the node.',
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
displayName: 'Notes In Flow',
|
||||||
|
name: 'notesInFlow',
|
||||||
|
type: 'boolean',
|
||||||
|
default: false,
|
||||||
|
noDataExpression: true,
|
||||||
|
description: 'If activated it will display the above notes in the flow as subtitle.',
|
||||||
|
},
|
||||||
{
|
{
|
||||||
displayName: 'Node Color',
|
displayName: 'Node Color',
|
||||||
name: 'color',
|
name: 'color',
|
||||||
|
@ -438,6 +447,11 @@ export default mixins(
|
||||||
Vue.set(this.nodeValues, 'continueOnFail', this.node.continueOnFail);
|
Vue.set(this.nodeValues, 'continueOnFail', this.node.continueOnFail);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (this.node.notesInFlow) {
|
||||||
|
foundNodeSettings.push('notesInFlow');
|
||||||
|
Vue.set(this.nodeValues, 'notesInFlow', this.node.notesInFlow);
|
||||||
|
}
|
||||||
|
|
||||||
if (this.node.retryOnFail) {
|
if (this.node.retryOnFail) {
|
||||||
foundNodeSettings.push('retryOnFail');
|
foundNodeSettings.push('retryOnFail');
|
||||||
Vue.set(this.nodeValues, 'retryOnFail', this.node.retryOnFail);
|
Vue.set(this.nodeValues, 'retryOnFail', this.node.retryOnFail);
|
||||||
|
|
|
@ -79,9 +79,13 @@ export class FacebookGraphApi implements INodeType {
|
||||||
type: 'options',
|
type: 'options',
|
||||||
options: [
|
options: [
|
||||||
{
|
{
|
||||||
name: 'Latest',
|
name: 'Default',
|
||||||
value: '',
|
value: '',
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
name: 'v7.0',
|
||||||
|
value: 'v7.0',
|
||||||
|
},
|
||||||
{
|
{
|
||||||
name: 'v6.0',
|
name: 'v6.0',
|
||||||
value: 'v6.0',
|
value: 'v6.0',
|
||||||
|
@ -110,10 +114,6 @@ export class FacebookGraphApi implements INodeType {
|
||||||
name: 'v3.0',
|
name: 'v3.0',
|
||||||
value: 'v3.0',
|
value: 'v3.0',
|
||||||
},
|
},
|
||||||
{
|
|
||||||
name: 'v2.12',
|
|
||||||
value: 'v2.12',
|
|
||||||
},
|
|
||||||
],
|
],
|
||||||
default: '',
|
default: '',
|
||||||
description: 'The version of the Graph API to be used in the request.',
|
description: 'The version of the Graph API to be used in the request.',
|
||||||
|
|
|
@ -11,22 +11,33 @@ import {
|
||||||
|
|
||||||
import {
|
import {
|
||||||
IDataObject,
|
IDataObject,
|
||||||
|
ICredentialDataDecryptedObject,
|
||||||
} from 'n8n-workflow';
|
} from 'n8n-workflow';
|
||||||
|
|
||||||
export async function jiraSoftwareCloudApiRequest(this: IHookFunctions | IExecuteFunctions | IExecuteSingleFunctions | ILoadOptionsFunctions, endpoint: string, method: string, body: any = {}, query?: IDataObject, uri?: string): Promise<any> { // tslint:disable-line:no-any
|
export async function jiraSoftwareCloudApiRequest(this: IHookFunctions | IExecuteFunctions | IExecuteSingleFunctions | ILoadOptionsFunctions, endpoint: string, method: string, body: any = {}, query?: IDataObject, uri?: string): Promise<any> { // tslint:disable-line:no-any
|
||||||
let data; let domain;
|
let data; let domain;
|
||||||
const jiraCloudCredentials = this.getCredentials('jiraSoftwareCloudApi');
|
|
||||||
const jiraServerCredentials = this.getCredentials('jiraSoftwareServerApi');
|
const jiraVersion = this.getNodeParameter('jiraVersion', 0) as string;
|
||||||
if (jiraCloudCredentials === undefined && jiraServerCredentials === undefined) {
|
|
||||||
|
let jiraCredentials: ICredentialDataDecryptedObject | undefined;
|
||||||
|
if (jiraVersion === 'server') {
|
||||||
|
jiraCredentials = this.getCredentials('jiraSoftwareServerApi');
|
||||||
|
} else {
|
||||||
|
jiraCredentials = this.getCredentials('jiraSoftwareCloudApi');
|
||||||
|
}
|
||||||
|
|
||||||
|
if (jiraCredentials === undefined) {
|
||||||
throw new Error('No credentials got returned!');
|
throw new Error('No credentials got returned!');
|
||||||
}
|
}
|
||||||
if (jiraCloudCredentials !== undefined) {
|
|
||||||
domain = jiraCloudCredentials!.domain;
|
if (jiraVersion === 'server') {
|
||||||
data = Buffer.from(`${jiraCloudCredentials!.email}:${jiraCloudCredentials!.apiToken}`).toString('base64');
|
domain = jiraCredentials!.domain;
|
||||||
|
data = Buffer.from(`${jiraCredentials!.email}:${jiraCredentials!.password}`).toString('base64');
|
||||||
} else {
|
} else {
|
||||||
domain = jiraServerCredentials!.domain;
|
domain = jiraCredentials!.domain;
|
||||||
data = Buffer.from(`${jiraServerCredentials!.email}:${jiraServerCredentials!.password}`).toString('base64');
|
data = Buffer.from(`${jiraCredentials!.email}:${jiraCredentials!.apiToken}`).toString('base64');
|
||||||
}
|
}
|
||||||
|
|
||||||
const options: OptionsWithUri = {
|
const options: OptionsWithUri = {
|
||||||
headers: {
|
headers: {
|
||||||
Authorization: `Basic ${data}`,
|
Authorization: `Basic ${data}`,
|
||||||
|
|
|
@ -81,6 +81,9 @@ export const issueFields = [
|
||||||
},
|
},
|
||||||
typeOptions: {
|
typeOptions: {
|
||||||
loadOptionsMethod: 'getProjects',
|
loadOptionsMethod: 'getProjects',
|
||||||
|
loadOptionsDependsOn: [
|
||||||
|
'jiraVersion',
|
||||||
|
],
|
||||||
},
|
},
|
||||||
description: 'Project',
|
description: 'Project',
|
||||||
},
|
},
|
||||||
|
@ -171,6 +174,31 @@ export const issueFields = [
|
||||||
default: [],
|
default: [],
|
||||||
required : false,
|
required : false,
|
||||||
description: 'Labels',
|
description: 'Labels',
|
||||||
|
displayOptions: {
|
||||||
|
show: {
|
||||||
|
'/jiraVersion': [
|
||||||
|
'cloud',
|
||||||
|
],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
displayName: 'Labels',
|
||||||
|
name: 'serverLabels',
|
||||||
|
type: 'string',
|
||||||
|
default: [],
|
||||||
|
required : false,
|
||||||
|
description: 'Labels',
|
||||||
|
displayOptions: {
|
||||||
|
show: {
|
||||||
|
'/jiraVersion': [
|
||||||
|
'server',
|
||||||
|
],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
typeOptions: {
|
||||||
|
multipleValues: true,
|
||||||
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
displayName: 'Parent Issue Key',
|
displayName: 'Parent Issue Key',
|
||||||
|
@ -281,6 +309,31 @@ export const issueFields = [
|
||||||
default: [],
|
default: [],
|
||||||
required : false,
|
required : false,
|
||||||
description: 'Labels',
|
description: 'Labels',
|
||||||
|
displayOptions: {
|
||||||
|
show: {
|
||||||
|
'/jiraVersion': [
|
||||||
|
'cloud',
|
||||||
|
],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
displayName: 'Labels',
|
||||||
|
name: 'serverLabels',
|
||||||
|
type: 'string',
|
||||||
|
default: [],
|
||||||
|
required : false,
|
||||||
|
description: 'Labels',
|
||||||
|
displayOptions: {
|
||||||
|
show: {
|
||||||
|
'/jiraVersion': [
|
||||||
|
'server',
|
||||||
|
],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
typeOptions: {
|
||||||
|
multipleValues: true,
|
||||||
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
displayName: 'Parent Issue Key',
|
displayName: 'Parent Issue Key',
|
||||||
|
|
|
@ -111,9 +111,10 @@ export class JiraSoftwareCloud implements INodeType {
|
||||||
// select them easily
|
// select them easily
|
||||||
async getProjects(this: ILoadOptionsFunctions): Promise<INodePropertyOptions[]> {
|
async getProjects(this: ILoadOptionsFunctions): Promise<INodePropertyOptions[]> {
|
||||||
const returnData: INodePropertyOptions[] = [];
|
const returnData: INodePropertyOptions[] = [];
|
||||||
const jiraCloudCredentials = this.getCredentials('jiraSoftwareCloudApi');
|
const jiraVersion = this.getCurrentNodeParameter('jiraVersion') as string;
|
||||||
|
|
||||||
let endpoint = '/project/search';
|
let endpoint = '/project/search';
|
||||||
if (jiraCloudCredentials === undefined) {
|
if (jiraVersion === 'server') {
|
||||||
endpoint = '/project';
|
endpoint = '/project';
|
||||||
}
|
}
|
||||||
let projects = await jiraSoftwareCloudApiRequest.call(this, endpoint, 'GET');
|
let projects = await jiraSoftwareCloudApiRequest.call(this, endpoint, 'GET');
|
||||||
|
@ -139,9 +140,9 @@ export class JiraSoftwareCloud implements INodeType {
|
||||||
const returnData: INodePropertyOptions[] = [];
|
const returnData: INodePropertyOptions[] = [];
|
||||||
|
|
||||||
const issueTypes = await jiraSoftwareCloudApiRequest.call(this, '/issuetype', 'GET');
|
const issueTypes = await jiraSoftwareCloudApiRequest.call(this, '/issuetype', 'GET');
|
||||||
|
const jiraVersion = this.getCurrentNodeParameter('jiraVersion') as string;
|
||||||
for (const issueType of issueTypes) {
|
if (jiraVersion === 'server') {
|
||||||
if (issueType.scope.project.id === projectId) {
|
for (const issueType of issueTypes) {
|
||||||
const issueTypeName = issueType.name;
|
const issueTypeName = issueType.name;
|
||||||
const issueTypeId = issueType.id;
|
const issueTypeId = issueType.id;
|
||||||
|
|
||||||
|
@ -150,7 +151,20 @@ export class JiraSoftwareCloud implements INodeType {
|
||||||
value: issueTypeId,
|
value: issueTypeId,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
for (const issueType of issueTypes) {
|
||||||
|
if (issueType.scope.project.id === projectId) {
|
||||||
|
const issueTypeName = issueType.name;
|
||||||
|
const issueTypeId = issueType.id;
|
||||||
|
|
||||||
|
returnData.push({
|
||||||
|
name: issueTypeName,
|
||||||
|
value: issueTypeId,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return returnData;
|
return returnData;
|
||||||
},
|
},
|
||||||
|
|
||||||
|
@ -196,18 +210,37 @@ export class JiraSoftwareCloud implements INodeType {
|
||||||
// select them easily
|
// select them easily
|
||||||
async getUsers(this: ILoadOptionsFunctions): Promise<INodePropertyOptions[]> {
|
async getUsers(this: ILoadOptionsFunctions): Promise<INodePropertyOptions[]> {
|
||||||
const returnData: INodePropertyOptions[] = [];
|
const returnData: INodePropertyOptions[] = [];
|
||||||
|
const jiraVersion = this.getCurrentNodeParameter('jiraVersion') as string;
|
||||||
|
if (jiraVersion === 'server') {
|
||||||
|
// the interface call must bring username
|
||||||
|
const users = await jiraSoftwareCloudApiRequest.call(this, '/user/search', 'GET', {},
|
||||||
|
{
|
||||||
|
username: "'",
|
||||||
|
}
|
||||||
|
);
|
||||||
|
for (const user of users) {
|
||||||
|
const userName = user.displayName;
|
||||||
|
const userId = user.name;
|
||||||
|
|
||||||
const users = await jiraSoftwareCloudApiRequest.call(this, '/users/search', 'GET');
|
returnData.push({
|
||||||
|
name: userName,
|
||||||
|
value: userId,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
const users = await jiraSoftwareCloudApiRequest.call(this, '/users/search', 'GET');
|
||||||
|
|
||||||
for (const user of users) {
|
for (const user of users) {
|
||||||
const userName = user.displayName;
|
const userName = user.displayName;
|
||||||
const userId = user.accountId;
|
const userId = user.accountId;
|
||||||
|
|
||||||
returnData.push({
|
returnData.push({
|
||||||
name: userName,
|
name: userName,
|
||||||
value: userId,
|
value: userId,
|
||||||
});
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return returnData;
|
return returnData;
|
||||||
},
|
},
|
||||||
|
|
||||||
|
@ -258,6 +291,8 @@ export class JiraSoftwareCloud implements INodeType {
|
||||||
|
|
||||||
const resource = this.getNodeParameter('resource', 0) as string;
|
const resource = this.getNodeParameter('resource', 0) as string;
|
||||||
const operation = this.getNodeParameter('operation', 0) as string;
|
const operation = this.getNodeParameter('operation', 0) as string;
|
||||||
|
const jiraVersion = this.getNodeParameter('jiraVersion', 0) as string;
|
||||||
|
|
||||||
|
|
||||||
for (let i = 0; i < length; i++) {
|
for (let i = 0; i < length; i++) {
|
||||||
if (resource === 'issue') {
|
if (resource === 'issue') {
|
||||||
|
@ -280,15 +315,24 @@ export class JiraSoftwareCloud implements INodeType {
|
||||||
if (additionalFields.labels) {
|
if (additionalFields.labels) {
|
||||||
fields.labels = additionalFields.labels as string[];
|
fields.labels = additionalFields.labels as string[];
|
||||||
}
|
}
|
||||||
|
if (additionalFields.serverLabels) {
|
||||||
|
fields.labels = additionalFields.serverLabels as string[];
|
||||||
|
}
|
||||||
if (additionalFields.priority) {
|
if (additionalFields.priority) {
|
||||||
fields.priority = {
|
fields.priority = {
|
||||||
id: additionalFields.priority as string,
|
id: additionalFields.priority as string,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
if (additionalFields.assignee) {
|
if (additionalFields.assignee) {
|
||||||
fields.assignee = {
|
if (jiraVersion === 'server') {
|
||||||
id: additionalFields.assignee as string,
|
fields.assignee = {
|
||||||
};
|
name: additionalFields.assignee as string,
|
||||||
|
};
|
||||||
|
} else {
|
||||||
|
fields.assignee = {
|
||||||
|
id: additionalFields.assignee as string,
|
||||||
|
};
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (additionalFields.description) {
|
if (additionalFields.description) {
|
||||||
fields.description = additionalFields.description as string;
|
fields.description = additionalFields.description as string;
|
||||||
|
@ -333,15 +377,24 @@ export class JiraSoftwareCloud implements INodeType {
|
||||||
if (updateFields.labels) {
|
if (updateFields.labels) {
|
||||||
fields.labels = updateFields.labels as string[];
|
fields.labels = updateFields.labels as string[];
|
||||||
}
|
}
|
||||||
|
if (updateFields.serverLabels) {
|
||||||
|
fields.labels = updateFields.serverLabels as string[];
|
||||||
|
}
|
||||||
if (updateFields.priority) {
|
if (updateFields.priority) {
|
||||||
fields.priority = {
|
fields.priority = {
|
||||||
id: updateFields.priority as string,
|
id: updateFields.priority as string,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
if (updateFields.assignee) {
|
if (updateFields.assignee) {
|
||||||
fields.assignee = {
|
if (jiraVersion === 'server') {
|
||||||
id: updateFields.assignee as string,
|
fields.assignee = {
|
||||||
};
|
name: updateFields.assignee as string,
|
||||||
|
};
|
||||||
|
} else {
|
||||||
|
fields.assignee = {
|
||||||
|
id: updateFields.assignee as string,
|
||||||
|
};
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (updateFields.description) {
|
if (updateFields.description) {
|
||||||
fields.description = updateFields.description as string;
|
fields.description = updateFields.description as string;
|
||||||
|
|
|
@ -97,6 +97,11 @@ export class Mattermost implements INodeType {
|
||||||
value: 'delete',
|
value: 'delete',
|
||||||
description: 'Soft-deletes a channel',
|
description: 'Soft-deletes a channel',
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
name: 'Members',
|
||||||
|
value: 'members',
|
||||||
|
description: 'Returns the members of a channel.',
|
||||||
|
},
|
||||||
{
|
{
|
||||||
name: 'Restore',
|
name: 'Restore',
|
||||||
value: 'restore',
|
value: 'restore',
|
||||||
|
@ -262,6 +267,97 @@ export class Mattermost implements INodeType {
|
||||||
description: 'The ID of the channel to soft-delete.',
|
description: 'The ID of the channel to soft-delete.',
|
||||||
},
|
},
|
||||||
|
|
||||||
|
// ----------------------------------
|
||||||
|
// channel:members
|
||||||
|
// ----------------------------------
|
||||||
|
{
|
||||||
|
displayName: 'Team ID',
|
||||||
|
name: 'teamId',
|
||||||
|
type: 'options',
|
||||||
|
typeOptions: {
|
||||||
|
loadOptionsMethod: 'getTeams',
|
||||||
|
},
|
||||||
|
options: [],
|
||||||
|
default: '',
|
||||||
|
required: true,
|
||||||
|
displayOptions: {
|
||||||
|
show: {
|
||||||
|
operation: [
|
||||||
|
'members',
|
||||||
|
],
|
||||||
|
resource: [
|
||||||
|
'channel',
|
||||||
|
],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
description: 'The Mattermost Team.',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
displayName: 'Channel ID',
|
||||||
|
name: 'channelId',
|
||||||
|
type: 'options',
|
||||||
|
typeOptions: {
|
||||||
|
loadOptionsMethod: 'getChannelsInTeam',
|
||||||
|
loadOptionsDependsOn: [
|
||||||
|
'teamId',
|
||||||
|
],
|
||||||
|
},
|
||||||
|
options: [],
|
||||||
|
default: '',
|
||||||
|
required: true,
|
||||||
|
displayOptions: {
|
||||||
|
show: {
|
||||||
|
operation: [
|
||||||
|
'members',
|
||||||
|
],
|
||||||
|
resource: [
|
||||||
|
'channel',
|
||||||
|
],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
description: 'The Mattermost Team.',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
displayName: 'Return All',
|
||||||
|
name: 'returnAll',
|
||||||
|
type: 'boolean',
|
||||||
|
displayOptions: {
|
||||||
|
show: {
|
||||||
|
operation: [
|
||||||
|
'members',
|
||||||
|
],
|
||||||
|
resource: [
|
||||||
|
'channel',
|
||||||
|
],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
default: true,
|
||||||
|
description: 'If all results should be returned or only up to a given limit.',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
displayName: 'Limit',
|
||||||
|
name: 'limit',
|
||||||
|
type: 'number',
|
||||||
|
displayOptions: {
|
||||||
|
show: {
|
||||||
|
operation: [
|
||||||
|
'members',
|
||||||
|
],
|
||||||
|
resource: [
|
||||||
|
'channel',
|
||||||
|
],
|
||||||
|
returnAll: [
|
||||||
|
false,
|
||||||
|
],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
typeOptions: {
|
||||||
|
minValue: 1,
|
||||||
|
maxValue: 100,
|
||||||
|
},
|
||||||
|
default: 100,
|
||||||
|
description: 'How many results to return.',
|
||||||
|
},
|
||||||
|
|
||||||
// ----------------------------------
|
// ----------------------------------
|
||||||
// channel:restore
|
// channel:restore
|
||||||
|
@ -1049,10 +1145,42 @@ export class Mattermost implements INodeType {
|
||||||
return returnData;
|
return returnData;
|
||||||
},
|
},
|
||||||
|
|
||||||
|
// Get all the channels in a team
|
||||||
|
async getChannelsInTeam(this: ILoadOptionsFunctions): Promise<INodePropertyOptions[]> {
|
||||||
|
const teamId = this.getCurrentNodeParameter('teamId');
|
||||||
|
const endpoint = `users/me/teams/${teamId}/channels`;
|
||||||
|
const responseData = await apiRequest.call(this, 'GET', endpoint, {});
|
||||||
|
|
||||||
|
if (responseData === undefined) {
|
||||||
|
throw new Error('No data got returned');
|
||||||
|
}
|
||||||
|
|
||||||
|
const returnData: INodePropertyOptions[] = [];
|
||||||
|
let name: string;
|
||||||
|
for (const data of responseData) {
|
||||||
|
if (data.delete_at !== 0) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
const channelTypes: IDataObject = {
|
||||||
|
'O': 'public',
|
||||||
|
'P': 'private',
|
||||||
|
'D': 'direct',
|
||||||
|
};
|
||||||
|
|
||||||
|
name = `${data.name} (${channelTypes[data.type as string]})`;
|
||||||
|
|
||||||
|
returnData.push({
|
||||||
|
name,
|
||||||
|
value: data.id,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
return returnData;
|
||||||
|
},
|
||||||
|
|
||||||
async getTeams(this: ILoadOptionsFunctions): Promise<INodePropertyOptions[]> {
|
async getTeams(this: ILoadOptionsFunctions): Promise<INodePropertyOptions[]> {
|
||||||
const endpoint = 'teams';
|
const endpoint = 'users/me/teams';
|
||||||
const responseData = await apiRequest.call(this, 'GET', endpoint, {});
|
const responseData = await apiRequest.call(this, 'GET', endpoint, {});
|
||||||
|
|
||||||
if (responseData === undefined) {
|
if (responseData === undefined) {
|
||||||
|
@ -1156,6 +1284,19 @@ export class Mattermost implements INodeType {
|
||||||
const channelId = this.getNodeParameter('channelId', i) as string;
|
const channelId = this.getNodeParameter('channelId', i) as string;
|
||||||
endpoint = `channels/${channelId}`;
|
endpoint = `channels/${channelId}`;
|
||||||
|
|
||||||
|
} else if (operation === 'members') {
|
||||||
|
// ----------------------------------
|
||||||
|
// channel:members
|
||||||
|
// ----------------------------------
|
||||||
|
|
||||||
|
requestMethod = 'GET';
|
||||||
|
const channelId = this.getNodeParameter('channelId', i) as string;
|
||||||
|
const returnAll = this.getNodeParameter('returnAll', i) as boolean;
|
||||||
|
endpoint = `channels/${channelId}/members`;
|
||||||
|
if (returnAll === false) {
|
||||||
|
qs.per_page = this.getNodeParameter('limit', i) as number;
|
||||||
|
}
|
||||||
|
|
||||||
} else if (operation === 'restore') {
|
} else if (operation === 'restore') {
|
||||||
// ----------------------------------
|
// ----------------------------------
|
||||||
// channel:restore
|
// channel:restore
|
||||||
|
@ -1353,7 +1494,7 @@ export class Mattermost implements INodeType {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (returnAll === false) {
|
if (returnAll === false) {
|
||||||
qs.limit = this.getNodeParameter('limit', i) as number;
|
qs.per_page = this.getNodeParameter('limit', i) as number;
|
||||||
}
|
}
|
||||||
|
|
||||||
endpoint = `/users`;
|
endpoint = `/users`;
|
||||||
|
|
|
@ -69,7 +69,7 @@ export class Merge implements INodeType {
|
||||||
{
|
{
|
||||||
name: 'Wait',
|
name: 'Wait',
|
||||||
value: 'wait',
|
value: 'wait',
|
||||||
description: 'Waits till data of both inputs is available and will then output a single empty item. If supposed to wait for multiple nodes they have to get attached to input 2. Node will not output any data.',
|
description: 'Waits till data of both inputs is available and will then output a single empty item. Source Nodes must connect to both Input 1 and 2. This node only supports 2 Sources, if you need more Sources, connect multiple Merge nodes in series. This node will not output any data.',
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
default: 'append',
|
default: 'append',
|
||||||
|
|
|
@ -158,6 +158,33 @@ export class Redis implements INodeType {
|
||||||
description: 'The type of the key to get.',
|
description: 'The type of the key to get.',
|
||||||
},
|
},
|
||||||
|
|
||||||
|
{
|
||||||
|
displayName: 'Options',
|
||||||
|
name: 'options',
|
||||||
|
type: 'collection',
|
||||||
|
displayOptions: {
|
||||||
|
show: {
|
||||||
|
operation: [
|
||||||
|
'get'
|
||||||
|
],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
placeholder: 'Add Option',
|
||||||
|
default: {},
|
||||||
|
options: [
|
||||||
|
{
|
||||||
|
displayName: 'Dot Notation',
|
||||||
|
name: 'dotNotation',
|
||||||
|
type: 'boolean',
|
||||||
|
default: true,
|
||||||
|
description: `By default does dot-notation get used in property names.<br />
|
||||||
|
This means that "a.b" will set the property "b" underneath "a" so { "a": { "b": value} }.<br />
|
||||||
|
If that is not intended this can be deactivated, it will then set { "a.b": value } instead.
|
||||||
|
`,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
|
||||||
// ----------------------------------
|
// ----------------------------------
|
||||||
// keys
|
// keys
|
||||||
// ----------------------------------
|
// ----------------------------------
|
||||||
|
@ -292,7 +319,7 @@ export class Redis implements INodeType {
|
||||||
|
|
||||||
execute(this: IExecuteFunctions): Promise<INodeExecutionData[][]> {
|
execute(this: IExecuteFunctions): Promise<INodeExecutionData[][]> {
|
||||||
// Parses the given value in a number if it is one else returns a string
|
// Parses the given value in a number if it is one else returns a string
|
||||||
function getParsedValue (value: string): string | number {
|
function getParsedValue(value: string): string | number {
|
||||||
if (value.match(/^[\d\.]+$/) === null) {
|
if (value.match(/^[\d\.]+$/) === null) {
|
||||||
// Is a string
|
// Is a string
|
||||||
return value;
|
return value;
|
||||||
|
@ -306,7 +333,7 @@ export class Redis implements INodeType {
|
||||||
function convertInfoToObject(stringData: string): IDataObject {
|
function convertInfoToObject(stringData: string): IDataObject {
|
||||||
const returnData: IDataObject = {};
|
const returnData: IDataObject = {};
|
||||||
|
|
||||||
let key:string, value:string;
|
let key: string, value: string;
|
||||||
for (const line of stringData.split('\n')) {
|
for (const line of stringData.split('\n')) {
|
||||||
if (['#', ''].includes(line.charAt(0))) {
|
if (['#', ''].includes(line.charAt(0))) {
|
||||||
continue;
|
continue;
|
||||||
|
@ -450,7 +477,15 @@ export class Redis implements INodeType {
|
||||||
const keyType = this.getNodeParameter('keyType', itemIndex) as string;
|
const keyType = this.getNodeParameter('keyType', itemIndex) as string;
|
||||||
|
|
||||||
const value = await getValue(client, keyGet, keyType) || null;
|
const value = await getValue(client, keyGet, keyType) || null;
|
||||||
set(item.json, propertyName, value);
|
|
||||||
|
const options = this.getNodeParameter('options', itemIndex, {}) as IDataObject;
|
||||||
|
|
||||||
|
if (options.dotNotation === false) {
|
||||||
|
item.json[propertyName] = value;
|
||||||
|
} else {
|
||||||
|
set(item.json, propertyName, value);
|
||||||
|
}
|
||||||
|
|
||||||
returnItems.push(item);
|
returnItems.push(item);
|
||||||
} else if (operation === 'keys') {
|
} else if (operation === 'keys') {
|
||||||
const keyPattern = this.getNodeParameter('keyPattern', itemIndex) as string;
|
const keyPattern = this.getNodeParameter('keyPattern', itemIndex) as string;
|
||||||
|
@ -467,7 +502,7 @@ export class Redis implements INodeType {
|
||||||
}
|
}
|
||||||
|
|
||||||
for (const keyName of keys) {
|
for (const keyName of keys) {
|
||||||
set(item.json, keyName, await promises[keyName]);
|
item.json[keyName] = await promises[keyName];
|
||||||
}
|
}
|
||||||
returnItems.push(item);
|
returnItems.push(item);
|
||||||
} else if (operation === 'set') {
|
} else if (operation === 'set') {
|
||||||
|
|
|
@ -289,6 +289,7 @@ export interface INode {
|
||||||
type: string;
|
type: string;
|
||||||
position: [number, number];
|
position: [number, number];
|
||||||
disabled?: boolean;
|
disabled?: boolean;
|
||||||
|
notesInFlow?: boolean;
|
||||||
retryOnFail?: boolean;
|
retryOnFail?: boolean;
|
||||||
maxTries?: number;
|
maxTries?: number;
|
||||||
waitBetweenTries?: number;
|
waitBetweenTries?: number;
|
||||||
|
@ -680,7 +681,7 @@ export interface IWorkflowExecuteAdditionalData {
|
||||||
timezone: string;
|
timezone: string;
|
||||||
webhookBaseUrl: string;
|
webhookBaseUrl: string;
|
||||||
webhookTestBaseUrl: string;
|
webhookTestBaseUrl: string;
|
||||||
currentNodeParameters? : INodeParameters[];
|
currentNodeParameters? : INodeParameters;
|
||||||
}
|
}
|
||||||
|
|
||||||
export type WorkflowExecuteMode = 'cli' | 'error' | 'integrated' | 'internal' | 'manual' | 'retry' | 'trigger' | 'webhook';
|
export type WorkflowExecuteMode = 'cli' | 'error' | 'integrated' | 'internal' | 'manual' | 'retry' | 'trigger' | 'webhook';
|
||||||
|
|
Loading…
Reference in a new issue