diff --git a/packages/nodes-base/nodes/Bitbucket/BitbucketTrigger.node.ts b/packages/nodes-base/nodes/Bitbucket/BitbucketTrigger.node.ts index 665a7b1053..b93501cc6c 100644 --- a/packages/nodes-base/nodes/Bitbucket/BitbucketTrigger.node.ts +++ b/packages/nodes-base/nodes/Bitbucket/BitbucketTrigger.node.ts @@ -58,58 +58,36 @@ export class BitbucketTrigger implements INodeType { type: 'options', required: true, options: [ - { - name: 'User', - value: 'user', - }, - { - name: 'Team', - value: 'team', - }, { name: 'Repository', value: 'repository', }, + { + name: 'Workspace', + value: 'workspace', + }, ], - default: 'user', + default: 'workspace', description: 'The resource to operate on.', }, { - displayName: 'Events', - name: 'events', - type: 'multiOptions', - displayOptions: { - show: { - resource: [ - 'user', - ], - }, - }, - typeOptions: { - loadOptionsMethod: 'getUsersEvents', - }, - options: [], - required: true, - default: [], - description: 'The events to listen to.', - }, - { - displayName: 'Team', - name: 'team', + displayName: 'Workspace', + name: 'workspace', type: 'options', displayOptions: { show: { resource: [ - 'team', + 'workspace', + 'repository', ], }, }, typeOptions: { - loadOptionsMethod: 'getTeams', + loadOptionsMethod: 'getWorkspaces', }, required: true, default: '', - description: 'The team of which to listen to the events.', + description: 'The repository of which to listen to the events.', }, { displayName: 'Events', @@ -118,12 +96,12 @@ export class BitbucketTrigger implements INodeType { displayOptions: { show: { resource: [ - 'team', + 'workspace', ], }, }, typeOptions: { - loadOptionsMethod: 'getTeamEvents', + loadOptionsMethod: 'getWorkspaceEvents', }, options: [], required: true, @@ -143,6 +121,9 @@ export class BitbucketTrigger implements INodeType { }, typeOptions: { loadOptionsMethod: 'getRepositories', + loadOptionsDependsOn: [ + 'workspace', + ], }, required: true, default: '', @@ -208,89 +189,50 @@ export class BitbucketTrigger implements INodeType { }, }, loadOptions: { - // Get all the events to display them to user so that he can - // select them easily - async getUsersEvents(this: ILoadOptionsFunctions): Promise { + async getWorkspaceEvents(this: ILoadOptionsFunctions): Promise { const returnData: INodePropertyOptions[] = []; - const events = await bitbucketApiRequestAllItems.call(this, 'values', 'GET', '/hook_events/user'); + const events = await bitbucketApiRequestAllItems.call(this, 'values', 'GET', '/hook_events/workspace'); for (const event of events) { - const eventName = event.event; - const eventId = event.event; - const eventDescription = event.description; returnData.push({ - name: eventName, - value: eventId, - description: eventDescription, + name: event.event, + value: event.event, + description: event.description, }); } return returnData; }, - // Get all the events to display them to user so that he can - // select them easily - async getTeamEvents(this: ILoadOptionsFunctions): Promise { - const returnData: INodePropertyOptions[] = []; - const events = await bitbucketApiRequestAllItems.call(this, 'values', 'GET', '/hook_events/team'); - for (const event of events) { - const eventName = event.event; - const eventId = event.event; - const eventDescription = event.description; - returnData.push({ - name: eventName, - value: eventId, - description: eventDescription, - }); - } - return returnData; - }, - // Get all the events to display them to user so that he can - // select them easily async getRepositoriesEvents(this: ILoadOptionsFunctions): Promise { const returnData: INodePropertyOptions[] = []; const events = await bitbucketApiRequestAllItems.call(this, 'values', 'GET', '/hook_events/repository'); for (const event of events) { - const eventName = event.event; - const eventId = event.event; - const eventDescription = event.description; returnData.push({ - name: eventName, - value: eventId, - description: eventDescription, + name: event.event, + value: event.event, + description: event.description, }); } return returnData; }, - // Get all the repositories to display them to user so that he can - // select them easily async getRepositories(this: ILoadOptionsFunctions): Promise { - const credentials = await this.getCredentials('bitbucketApi'); const returnData: INodePropertyOptions[] = []; - const repositories = await bitbucketApiRequestAllItems.call(this, 'values', 'GET', `/repositories/${credentials!.username}`); + const workspace = this.getCurrentNodeParameter('workspace') as string; + const repositories = await bitbucketApiRequestAllItems.call(this, 'values', 'GET', `/repositories/${workspace}`); for (const repository of repositories) { - const repositoryName = repository.slug; - const repositoryId = repository.slug; - const repositoryDescription = repository.description; returnData.push({ - name: repositoryName, - value: repositoryId, - description: repositoryDescription, + name: repository.slug, + value: repository.slug, + description: repository.description, }); } return returnData; }, - // Get all the teams to display them to user so that he can - // select them easily - async getTeams(this: ILoadOptionsFunctions): Promise { + async getWorkspaces(this: ILoadOptionsFunctions): Promise { const returnData: INodePropertyOptions[] = []; - const qs: IDataObject = { - role: 'member', - }; - const teams = await bitbucketApiRequestAllItems.call(this, 'values', 'GET', '/teams', {}, qs); - for (const team of teams) { - const teamName = team.display_name; - const teamId = team.username; + const workspaces = await bitbucketApiRequestAllItems.call(this, 'values', 'GET', `/workspaces`); + for (const workspace of workspaces) { returnData.push({ - name: teamName, - value: teamId, + name: workspace.name, + value: workspace.slug, }); } return returnData; @@ -302,29 +244,25 @@ export class BitbucketTrigger implements INodeType { default: { async checkExists(this: IHookFunctions): Promise { let endpoint = ''; - const credentials = await this.getCredentials('bitbucketApi'); const resource = this.getNodeParameter('resource', 0) as string; + const workspace = this.getNodeParameter('workspace', 0) as string; + const webhookUrl = this.getNodeWebhookUrl('default'); const webhookData = this.getWorkflowStaticData('node'); - if (webhookData.webhookId === undefined) { - return false; - } - if (resource === 'user') { - endpoint = `/users/${credentials!.username}/hooks/${webhookData.webhookId}`; - } - if (resource === 'team') { - const team = this.getNodeParameter('team', 0) as string; - endpoint = `/teams/${team}/hooks/${webhookData.webhookId}`; + if (resource === 'workspace') { + endpoint = `/workspaces/${workspace}/hooks`; } if (resource === 'repository') { const repository = this.getNodeParameter('repository', 0) as string; - endpoint = `/repositories/${credentials!.username}/${repository}/hooks/${webhookData.webhookId}`; + endpoint = `/repositories/${workspace}/${repository}/hooks`; } - try { - await bitbucketApiRequest.call(this, 'GET', endpoint); - } catch (error) { - return false; + const { values: hooks } = await bitbucketApiRequest.call(this, 'GET', endpoint); + for (const hook of hooks) { + if (webhookUrl === hook.url && hook.active === true) { + webhookData.webhookId = hook.uuid.replace('{', '').replace('}', ''); + return true; + } } - return true; + return false; }, async create(this: IHookFunctions): Promise { let responseData; @@ -333,18 +271,14 @@ export class BitbucketTrigger implements INodeType { const webhookData = this.getWorkflowStaticData('node'); const events = this.getNodeParameter('events') as string[]; const resource = this.getNodeParameter('resource', 0) as string; - const credentials = await this.getCredentials('bitbucketApi'); + const workspace = this.getNodeParameter('workspace', 0) as string; - if (resource === 'user') { - endpoint = `/users/${credentials!.username}/hooks`; - } - if (resource === 'team') { - const team = this.getNodeParameter('team', 0) as string; - endpoint = `/teams/${team}/hooks`; + if (resource === 'workspace') { + endpoint = `/workspaces/${workspace}/hooks`; } if (resource === 'repository') { const repository = this.getNodeParameter('repository', 0) as string; - endpoint = `/repositories/${credentials!.username}/${repository}/hooks`; + endpoint = `/repositories/${workspace}/${repository}/hooks`; } const body: IDataObject = { description: 'n8n webhook', @@ -359,22 +293,18 @@ export class BitbucketTrigger implements INodeType { async delete(this: IHookFunctions): Promise { let endpoint = ''; const webhookData = this.getWorkflowStaticData('node'); - const credentials = await this.getCredentials('bitbucketApi'); + const workspace = this.getNodeParameter('workspace', 0) as string; const resource = this.getNodeParameter('resource', 0) as string; - if (resource === 'user') { - endpoint = `/users/${credentials!.username}/hooks/${webhookData.webhookId}`; - } - if (resource === 'team') { - const team = this.getNodeParameter('team', 0) as string; - endpoint = `/teams/${team}/hooks/${webhookData.webhookId}`; + if (resource === 'workspace') { + endpoint = `/workspaces/${workspace}/hooks/${webhookData.webhookId}`; } if (resource === 'repository') { const repository = this.getNodeParameter('repository', 0) as string; - endpoint = `/repositories/${credentials!.username}/${repository}/hooks/${webhookData.webhookId}`; + endpoint = `/repositories/${workspace}/${repository}/hooks/${webhookData.webhookId}`; } try { await bitbucketApiRequest.call(this, 'DELETE', endpoint); - } catch(error) { + } catch (error) { return false; } delete webhookData.webhookId;