├── types ├── callback.d.ts ├── models │ ├── attachment │ │ ├── properties.d.ts │ │ ├── applicationRoles.d.ts │ │ ├── index.d.ts │ │ └── author.d.ts │ ├── issueType │ │ ├── scope.d.ts │ │ └── index.d.ts │ ├── index.d.ts │ ├── labels │ │ └── index.d.ts │ ├── version │ │ └── index.d.ts │ └── temp.d.ts ├── api │ ├── auth.d.ts │ ├── labels.d.ts │ ├── applicationProperties.d.ts │ ├── auditing.d.ts │ ├── backlog.d.ts │ ├── index.d.ts │ ├── attachment.d.ts │ ├── avatar.d.ts │ ├── search.d.ts │ ├── issueType.d.ts │ ├── epic.d.ts │ ├── developmentInformation.d.ts │ ├── sprint.d.ts │ ├── version.d.ts │ ├── project.d.ts │ ├── user.d.ts │ ├── board.d.ts │ └── issue.d.ts ├── tsconfig.json ├── config.d.ts └── index.d.ts ├── .gitignore ├── .editorconfig ├── jsdoc.json ├── package.json ├── api ├── jql.js ├── permissions.js ├── licenseValidator.js ├── securityLevel.js ├── serverInfo.js ├── workflow.js ├── customFieldOption.js ├── projectValidate.js ├── password.js ├── status.js ├── priority.js ├── settings.js ├── field.js ├── resolution.js ├── groups.js ├── statusCategory.js ├── projectCategory.js ├── labels.js ├── auth.js ├── myPermissions.js ├── groupUserPicker.js ├── backlog.js ├── myself.js ├── dashboard.js ├── licenseRole.js ├── application-properties.js ├── auditing.js ├── reindex.js ├── attachment.js ├── myPreferences.js ├── worklog.js ├── developmentInformation.js ├── issueLink.js ├── webhook.js ├── search.js ├── avatar.js ├── component.js ├── issueLinkType.js ├── comment.js ├── issueType.js ├── roles.js ├── group.js ├── sprint.js ├── permission-scheme.js ├── epic.js └── screens.js ├── LICENSE └── lib ├── error.js └── oauth_util.js /types/callback.d.ts: -------------------------------------------------------------------------------- 1 | export type Callback = (err: any, data: TData) => void; 2 | -------------------------------------------------------------------------------- /types/models/attachment/properties.d.ts: -------------------------------------------------------------------------------- 1 | export interface Properties { 2 | [key: string]: string; 3 | } 4 | -------------------------------------------------------------------------------- /types/models/issueType/scope.d.ts: -------------------------------------------------------------------------------- 1 | export interface Scope { 2 | type: 'PROJECT'; 3 | project: { id: string }; 4 | } 5 | -------------------------------------------------------------------------------- /types/models/index.d.ts: -------------------------------------------------------------------------------- 1 | export * from './attachment'; 2 | export * from './issueType'; 3 | export * from './labels'; 4 | export * from './version'; 5 | 6 | // TODO remove it 7 | export * from './temp'; 8 | -------------------------------------------------------------------------------- /types/models/labels/index.d.ts: -------------------------------------------------------------------------------- 1 | export interface PageBeanString { 2 | self: string; 3 | nextPage: string; 4 | maxResults: number; 5 | startAt: number; 6 | total: number; 7 | isLast: boolean; 8 | values: string[]; 9 | } 10 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | #intellij files 2 | .idea 3 | *.iml 4 | 5 | # Logs 6 | logs 7 | *.log 8 | 9 | # Dependency directory 10 | # https://www.npmjs.org/doc/misc/npm-faq.html#should-i-check-my-node_modules-folder-into-git- 11 | node_modules 12 | package-lock.json 13 | yarn.lock 14 | -------------------------------------------------------------------------------- /types/models/attachment/applicationRoles.d.ts: -------------------------------------------------------------------------------- 1 | import { Properties } from './properties'; 2 | 3 | export interface ApplicationRoles { 4 | size: number; 5 | items: Properties[]; 6 | pagingCallback: Properties; 7 | callback: Properties; 8 | "max-results": number; 9 | } 10 | -------------------------------------------------------------------------------- /types/models/issueType/index.d.ts: -------------------------------------------------------------------------------- 1 | import { Scope } from "./scope"; 2 | 3 | export interface IssueType { 4 | self: string; 5 | id: string; 6 | description: string; 7 | iconUrl: string; 8 | name: string; 9 | subtask: boolean; 10 | avatarId: number; 11 | entityId?: string; 12 | scope?: Scope; 13 | } 14 | -------------------------------------------------------------------------------- /.editorconfig: -------------------------------------------------------------------------------- 1 | root = true 2 | 3 | [*] 4 | indent_style = space 5 | indent_size = 2 6 | tab_width = 2 7 | end_of_line = lf 8 | charset = utf-8 9 | trim_trailing_whitespace = true 10 | insert_final_newline = true 11 | max_line_length = 120 12 | 13 | [*.html] 14 | indent_size = 4 15 | tab_width = 4 16 | max_line_length = off 17 | -------------------------------------------------------------------------------- /types/api/auth.d.ts: -------------------------------------------------------------------------------- 1 | import JiraClient from '../index'; 2 | import { Callback } from '../callback'; 3 | 4 | export class Auth { 5 | logout( 6 | callback?: Callback 7 | ): Promise; 8 | 9 | login( 10 | opts: { 11 | username: string, 12 | password: string 13 | }, 14 | callback?: Callback 15 | ): Promise; 16 | 17 | currentUser( 18 | callback?: Callback 19 | ): Promise; 20 | } 21 | -------------------------------------------------------------------------------- /jsdoc.json: -------------------------------------------------------------------------------- 1 | { 2 | "source": { 3 | "include": ["."], 4 | "exclude": ["./node_modules"], 5 | "includePattern": ".+\\.js(doc)?$", 6 | "excludePattern": "(^|\\/|\\\\)_" 7 | }, 8 | "opts": { 9 | "destination": "./docs/", 10 | "recurse": true, 11 | "readme": "./README.md", 12 | "package": "./package.json" 13 | }, 14 | "plugins": ["plugins/markdown"], 15 | "markdown": { 16 | "parser": "gfm" 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /types/api/labels.d.ts: -------------------------------------------------------------------------------- 1 | import { Callback } from "../callback"; 2 | import { PageBeanString } from "../models"; 3 | 4 | export class Labels { 5 | getLabels( 6 | ops: { 7 | query: string; 8 | }, 9 | callback?: Callback 10 | ): Promise; 11 | 12 | getAllLabels( 13 | opts?: { 14 | startAt?: number; 15 | maxResults?: number; 16 | }, 17 | callback?: Callback 18 | ): Promise; 19 | } 20 | -------------------------------------------------------------------------------- /types/api/applicationProperties.d.ts: -------------------------------------------------------------------------------- 1 | import { Callback } from "../callback"; 2 | 3 | export class ApplicationProperties { 4 | getProperties( 5 | opts?: { 6 | key?: string; 7 | permissionLevel?: string; 8 | keyFilter?: string; 9 | }, 10 | callback?: Callback, 11 | ): Promise; 12 | 13 | setProperty( 14 | opts: { 15 | id: any; 16 | property: any; 17 | }, 18 | callback?: Callback, 19 | ): Promise; 20 | } 21 | -------------------------------------------------------------------------------- /types/api/auditing.d.ts: -------------------------------------------------------------------------------- 1 | import JiraClient from '../index'; 2 | import { Callback } from '../callback'; 3 | 4 | export class Auditing { 5 | getAudits( 6 | opts: { 7 | offset: number, 8 | limit: number, 9 | filter: any, 10 | from: number, 11 | to: number 12 | }, 13 | callback?: Callback 14 | ): Promise; 15 | 16 | createAudit( 17 | opts: { 18 | audit: any 19 | }, 20 | callback?: Callback 21 | ): Promise; 22 | } 23 | -------------------------------------------------------------------------------- /types/models/attachment/index.d.ts: -------------------------------------------------------------------------------- 1 | import { Author } from './author'; 2 | import { Properties } from './properties'; 3 | 4 | export interface AttachmentMetadata { 5 | id: number; 6 | self: string; 7 | filename: string; 8 | author: Author; 9 | created: string; 10 | size: number; 11 | mimeType: string; 12 | properties: Properties; 13 | content: string; 14 | thumbnail: string; 15 | } 16 | 17 | export interface AttachmentSettings { 18 | enabled: boolean; 19 | uploadLimit: number; 20 | } 21 | -------------------------------------------------------------------------------- /types/models/attachment/author.d.ts: -------------------------------------------------------------------------------- 1 | import { ApplicationRoles } from "./applicationRoles"; 2 | 3 | export interface Author { 4 | self: string; 5 | key: string; 6 | accountId: string; 7 | accountType: string; 8 | name: string; 9 | emailAddress: string; 10 | avatarUrls: { [key: string]: string }; 11 | displayName: string; 12 | active: boolean; 13 | timeZone: string; 14 | locale: string; 15 | groups: ApplicationRoles; 16 | applicationRoles: ApplicationRoles; 17 | expand: string; 18 | } 19 | -------------------------------------------------------------------------------- /types/api/backlog.d.ts: -------------------------------------------------------------------------------- 1 | import { Callback } from "../callback"; 2 | 3 | export class Backlog { 4 | moveIssuesToBacklog( 5 | opts?: { 6 | issues?: string[]; 7 | }, 8 | callback?: Callback 9 | ): Promise; 10 | 11 | moveIssuesToBacklogForBoard( 12 | opts: { 13 | boardId: number; 14 | issues?: string[]; 15 | rankBeforeIssue?: string; 16 | rankAfterIssue?: string; 17 | rankCustomFieldId?: number; 18 | }, 19 | callback?: Callback 20 | ): Promise; 21 | } 22 | -------------------------------------------------------------------------------- /types/api/index.d.ts: -------------------------------------------------------------------------------- 1 | export * from './applicationProperties'; 2 | export * from './attachment'; 3 | export * from './auditing'; 4 | export * from './auth'; 5 | export * from './avatar'; 6 | export * from './backlog'; 7 | export * from './board'; 8 | export * from './developmentInformation'; 9 | export * from './epic'; 10 | export * from './issue'; 11 | export * from './issueType'; 12 | export * from './labels'; 13 | export * from './project'; 14 | export * from './search'; 15 | export * from './sprint'; 16 | export * from './user'; 17 | export * from './version'; 18 | -------------------------------------------------------------------------------- /types/api/attachment.d.ts: -------------------------------------------------------------------------------- 1 | import { Callback } from "../callback"; 2 | import { AttachmentMetadata } from "../models"; 3 | 4 | export class Attachment { 5 | getAttachment( 6 | opts: { 7 | attachmentId: string; 8 | }, 9 | callback?: Callback, 10 | ): Promise; 11 | 12 | deleteAttachment( 13 | opts: { 14 | attachmentId: string; 15 | }, 16 | callback?: Callback 17 | ): Promise; 18 | 19 | getGlobalAttachmentMetadata( 20 | opts?: any, 21 | callback?: Callback 22 | ): Promise; 23 | } 24 | -------------------------------------------------------------------------------- /types/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "module": "commonjs", 4 | "lib": [ 5 | "es6" 6 | ], 7 | "noImplicitAny": true, 8 | "noImplicitThis": true, 9 | "strictNullChecks": false, 10 | "strictFunctionTypes": true, 11 | "strict": true, 12 | "baseUrl": "../", 13 | "paths": { 14 | "jira-connector": [ 15 | "." 16 | ] 17 | }, 18 | "typeRoots": [ 19 | "../" 20 | ], 21 | "types": [], 22 | "noEmit": true, 23 | "forceConsistentCasingInFileNames": true 24 | }, 25 | "files": [ 26 | "index.d.ts" 27 | ] 28 | } 29 | -------------------------------------------------------------------------------- /types/api/avatar.d.ts: -------------------------------------------------------------------------------- 1 | import JiraClient from '../index'; 2 | import { Callback } from '../callback'; 3 | 4 | export class Avatar { 5 | getAvatars( 6 | opts: { 7 | avatarType: 'project' | 'user' 8 | }, 9 | callback?: Callback 10 | ): Promise; 11 | 12 | createTemporaryAvatar( 13 | opts: { 14 | avatarType: 'project' | 'user', 15 | avatarFilename: string, 16 | avatarFileSize: number, 17 | avatarFilePath: string 18 | }, 19 | callback?: Callback 20 | ): Promise; 21 | 22 | cropTemporaryAvatar( 23 | opts: { 24 | avatarType: 'project' | 'user', 25 | crop: any 26 | }, 27 | callback?: Callback 28 | ): Promise; 29 | } 30 | -------------------------------------------------------------------------------- /types/config.d.ts: -------------------------------------------------------------------------------- 1 | export interface Config { 2 | host: string; 3 | port?: number; 4 | 5 | timeout?: number; 6 | 7 | protocol?: string; 8 | path_prefix?: string; 9 | strictSSL?: boolean; 10 | version?: number | string; 11 | basic_auth?: { 12 | email?: string; 13 | api_token?: string; 14 | username?: string; 15 | password?: string; 16 | base64?: string; 17 | }; 18 | oauth?: { 19 | consumer_key: string; 20 | private_key: string; 21 | token: string; 22 | token_secret: string; 23 | }; 24 | jwt?: { 25 | iss: string; 26 | secret: string; 27 | expiry_time_seconds?: number; 28 | }; 29 | cookie_jar?: any; 30 | promise?: PromiseLike; 31 | request?: any; 32 | rejectUnauthorized?: any; 33 | } 34 | -------------------------------------------------------------------------------- /types/models/version/index.d.ts: -------------------------------------------------------------------------------- 1 | export interface Version { 2 | expand: string; 3 | self: string; 4 | id: string; 5 | description: string; 6 | name: string; 7 | archived: boolean; 8 | released: boolean; 9 | startDate: string; 10 | releaseDate: string; 11 | overdue: boolean; 12 | userStartDate: string; 13 | userReleaseDate: string; 14 | project: string; 15 | projectId: number; 16 | moveUnfixedIssuesTo: string; 17 | operations: Operation[]; 18 | issuesStatusForFixVersion: IssuesStatusForFixVersion; 19 | } 20 | 21 | export interface IssuesStatusForFixVersion { 22 | unmapped: number; 23 | toDo: number; 24 | inProgress: number; 25 | done: number; 26 | } 27 | 28 | export interface Operation { 29 | id: string; 30 | styleClass: string; 31 | iconClass: string; 32 | label: string; 33 | title: string; 34 | href: string; 35 | weight: number; 36 | } 37 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "jira-connector", 3 | "version": "3.1.0", 4 | "description": "Easy to use NodeJS wrapper for the Jira REST API.", 5 | "keywords": [ 6 | "JIRA", 7 | "REST", 8 | "OAuth" 9 | ], 10 | "files": [ 11 | "api/", 12 | "lib/", 13 | "types/", 14 | "index.js", 15 | "jsdoc.json" 16 | ], 17 | "main": "./index.js", 18 | "types": "./types/index.d.ts", 19 | "scripts": { 20 | "prepublishOnly": "npm run test", 21 | "test": "dtslint types" 22 | }, 23 | "author": "Caleb Brinkman ", 24 | "license": "MIT", 25 | "devDependencies": { 26 | "@types/request": "^2.48.4", 27 | "dtslint": "^2.0.2" 28 | }, 29 | "dependencies": { 30 | "atlassian-jwt": "^1.0.2", 31 | "mime-types": "^2.1.25", 32 | "oauth": "^0.9.15", 33 | "query-string": "^6.9.0", 34 | "request": "^2.88.0" 35 | }, 36 | "repository": { 37 | "type": "git", 38 | "url": "git@github.com:floralvikings/jira-connector.git" 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /api/jql.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | 3 | module.exports = JqlClient; 4 | 5 | /** 6 | * Used to access Jira REST endpoints in '/rest/api/2/jql/autocompletedata' 7 | * 8 | * @param {JiraClient} jiraClient 9 | * @constructor JqlClient 10 | */ 11 | function JqlClient(jiraClient) { 12 | this.jiraClient = jiraClient; 13 | 14 | /** 15 | * Returns the auto complete data required for JQL searches. 16 | * 17 | * @method getAutoCompleteData 18 | * @memberOf JqlClient# 19 | * @param opts The options sent to the Jira API. Ignored by this function. 20 | * @param [callback] Called when the autocomplete data is returned. 21 | * @return {Promise} Resolved when the autocomplete data is returned. 22 | */ 23 | this.getAutoCompleteData = function (opts, callback) { 24 | var options = { 25 | uri: this.jiraClient.buildURL('/jql/autocompletedata'), 26 | method: 'GET', 27 | json: true, 28 | followAllRedirects: true 29 | }; 30 | 31 | return this.jiraClient.makeRequest(options, callback) 32 | } 33 | } -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2019 Caleb Brinkman 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /api/permissions.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | 3 | module.exports = PermissionsClient; 4 | 5 | /** 6 | * Used to access Jira REST endpoints in '/rest/api/2/permissions' 7 | * 8 | * @param {JiraClient} jiraClient 9 | * @constructor PermissionsClient 10 | */ 11 | function PermissionsClient(jiraClient) { 12 | this.jiraClient = jiraClient; 13 | 14 | /** 15 | * Returns all permissions that are present in the JIRA instance 16 | * - Global, Project and the global ones added by plugins 17 | * 18 | * @method getAllPermissions 19 | * @memberOf PermissionsClient# 20 | * @param opts The request options sent to the Jira API. 21 | * @param [callback] Called when the permissions have been returned. 22 | * @return {Promise} Resolved when the permissions have been returned. 23 | */ 24 | this.getAllPermissions = function (opts, callback) { 25 | var options = { 26 | uri: this.jiraClient.buildURL('/permissions'), 27 | method: 'GET', 28 | json: true, 29 | followAllRedirects: true 30 | }; 31 | 32 | return this.jiraClient.makeRequest(options, callback); 33 | } 34 | } -------------------------------------------------------------------------------- /api/licenseValidator.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | 3 | module.exports = LicenseValidatorClient; 4 | 5 | /** 6 | * Used to access Jira REST endpoints in '/rest/api/2/licenseValidator' 7 | * 8 | * @param {JiraClient} jiraClient 9 | * @constructor LicenseValidatorClient 10 | */ 11 | function LicenseValidatorClient(jiraClient) { 12 | this.jiraClient = jiraClient; 13 | 14 | /** 15 | * 16 | * @method validateLicense 17 | * @memberOf LicenseValidatorClient# 18 | * @param opts The request options sent to the Jira API. 19 | * @param opts.license The license to validate. 20 | * @param [callback] Called when the license has been validated, or fails to validate. 21 | * @return {Promise} Resolved when the license has been validated, or fails to validate. 22 | */ 23 | this.validateLicense = function (opts, callback) { 24 | var options = { 25 | uri: this.jiraClient.buildURL('/licenseValidator'), 26 | method: 'POST', 27 | json: true, 28 | followAllRedirects: true, 29 | body: opts.license 30 | }; 31 | 32 | return this.jiraClient.makeRequest(options, callback); 33 | } 34 | } -------------------------------------------------------------------------------- /api/securityLevel.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | 3 | module.exports = SecurityLevelClient; 4 | 5 | /** 6 | * Used to access Jira REST endpoints in '/rest/api/2/securitylevel' 7 | * 8 | * @param {JiraClient} jiraClient 9 | * @constructor SecurityLevelClient 10 | */ 11 | function SecurityLevelClient(jiraClient) { 12 | this.jiraClient = jiraClient; 13 | 14 | /** 15 | * Get a full representation of the security level that has the given id. 16 | * 17 | * @method getSecurityLevel 18 | * @memberOf SecurityLevelClient# 19 | * @param opts The request options to send to the Jira API. 20 | * @param opts.securityLevelId The id of the security level to retrieve 21 | * @param [callback] Called when the security level has been retrieved. 22 | * @return {Promise} Resolved when the security level has been retrieved. 23 | */ 24 | this.getSecurityLevel = function (opts, callback) { 25 | var options = { 26 | uri: this.jiraClient.buildURL('/securitylevel/' + opts.securityLevelId), 27 | method: 'GET', 28 | json: true, 29 | followAllRedirects: true 30 | }; 31 | 32 | return this.jiraClient.makeRequest(options, callback); 33 | } 34 | } -------------------------------------------------------------------------------- /types/api/search.d.ts: -------------------------------------------------------------------------------- 1 | import { Callback } from "../callback"; 2 | 3 | export interface IssueResponse { 4 | expand: string; 5 | id: string; 6 | self: string; 7 | key: string; 8 | renderedFields: any; 9 | properties: any; 10 | names: any; 11 | schema: any; 12 | transitions: any[]; 13 | operations: any; 14 | editmeta: any; 15 | changelog: any; 16 | versionedRepresentations: any; 17 | fieldsToInclude: any; 18 | fields: any; 19 | } 20 | 21 | export interface SearchResult { 22 | expand: string; 23 | startAt: number; 24 | maxResults: number; 25 | total: number; 26 | issues: IssueResponse[]; 27 | warningMessages: string[]; 28 | names: any; 29 | schema: any; 30 | } 31 | 32 | export class Search { 33 | search( 34 | opts: { 35 | method?: 'GET' | 'POST' | 'get' | 'post' 36 | jql?: string; 37 | startAt?: number; 38 | maxResults?: number; 39 | validateQuery?: string | boolean | 'strict' | 'warn' | 'none' | 'true' | 'false'; 40 | expand?: string[]; 41 | properties?: string[]; 42 | fieldsByKeys?: boolean; 43 | timeout?: number; 44 | fields?: string[]; 45 | }, 46 | callback?: Callback 47 | ): Promise; 48 | } 49 | -------------------------------------------------------------------------------- /api/serverInfo.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | 3 | module.exports = ServerInfoClient; 4 | 5 | /** 6 | * Used to access Jira REST endpoints in '/rest/api/2/serverInfo' 7 | * @param {JiraClient} jiraClient 8 | * @constructor ServerInfoClient 9 | */ 10 | function ServerInfoClient(jiraClient) { 11 | this.jiraClient = jiraClient; 12 | 13 | /** 14 | * Returns general information about the current JIRA server. 15 | * 16 | * @method getServerInfo 17 | * @memberOf ServerInfoClient# 18 | * @param opts The request options sent to the Jira API. 19 | * @param {boolean} [opts.doHealthCheck] Whether to perform a health check on the server. 20 | * @param [callback] Called when the server info has been retrieved. 21 | * @return {Promise} Resolved when the server info has been retrieved. 22 | */ 23 | this.getServerInfo = function (opts, callback) { 24 | var options = { 25 | uri: this.jiraClient.buildURL('/serverInfo'), 26 | method: 'GET', 27 | json: true, 28 | followAllRedirects: true, 29 | qs: { 30 | doHealthCheck: opts.doHealthCheck 31 | } 32 | }; 33 | 34 | return this.jiraClient.makeRequest(options, callback); 35 | } 36 | } -------------------------------------------------------------------------------- /types/api/issueType.d.ts: -------------------------------------------------------------------------------- 1 | import { Callback } from "../callback"; 2 | import { IssueType as IssueTypeModel } from "../models"; 3 | 4 | export class IssueType { 5 | getAllIssueTypes( 6 | opts?: {}, 7 | callback?: Callback, 8 | ): Promise; 9 | 10 | createIssueType( 11 | opts: { 12 | name: string; 13 | description?: string; 14 | type?: 'subtype' | 'standard'; 15 | }, 16 | callback?: Callback, 17 | ): Promise; 18 | 19 | getIssueType( 20 | opts: { issueTypeId: string }, 21 | callback?: Callback, 22 | ): Promise; 23 | 24 | updateIssueType( 25 | opts: { 26 | issueTypeId: string; 27 | issueType: Partial<{ 28 | name: string; 29 | description: string; 30 | avatarId: string | number; 31 | }>; 32 | }, 33 | callback?: Callback, 34 | ): Promise; 35 | 36 | deleteIssueType( 37 | opts: { 38 | issueTypeId: string; 39 | alternativeIssueTypeId?: string; 40 | }, 41 | callback?: Callback, 42 | ): Promise; 43 | 44 | getAlternativeIssueTypes( 45 | opts: { issueTypeId: string }, 46 | callback?: Callback, 47 | ): Promise; 48 | } 49 | -------------------------------------------------------------------------------- /api/workflow.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | 3 | module.exports = WorkflowClient; 4 | 5 | /** 6 | * Used to access Jira REST endpoints in '/rest/api/2/workflow' 7 | * 8 | * @param {JiraClient} jiraClient 9 | * @constructor WorkflowClient 10 | */ 11 | function WorkflowClient(jiraClient) { 12 | this.jiraClient = jiraClient; 13 | 14 | /** 15 | * Returns all workflows. 16 | * 17 | * @method getWorkflows 18 | * @memberOf WorkflowClient# 19 | * @param {Object} opts The request options sent to the Jira API 20 | * @param {string} [opts.workflowName] The name of the workflow to retrieve. 21 | * @param [callback] Called when the workflow(s) have been retrieved. 22 | * @return {Promise} Resolved when the workflow(s) have been retrieved. 23 | */ 24 | this.getWorkflows = function (opts, callback) { 25 | var qs = {}; 26 | if (opts && typeof opts === 'object' && opts.hasOwnProperty('workflowName')) { 27 | qs.workflowName = opts.workflowName; 28 | } 29 | var options = { 30 | uri: this.jiraClient.buildURL('/workflow'), 31 | method: 'GET', 32 | json: true, 33 | followAllRedirects: true, 34 | qs: qs 35 | }; 36 | 37 | return this.jiraClient.makeRequest(options, callback); 38 | }; 39 | } 40 | -------------------------------------------------------------------------------- /types/api/epic.d.ts: -------------------------------------------------------------------------------- 1 | import { Callback } from "../callback"; 2 | 3 | export class Epic { 4 | getIssuesWithoutEpic(opts?: { 5 | startAt?: number; 6 | maxResults?: number; 7 | jql?: string; 8 | validateQuery?: boolean; 9 | fields?: string[]; 10 | expand?: string; 11 | }, callback?: Callback): Promise; 12 | removeIssuesFromEpic(opts?: { 13 | issues?: string[]; 14 | }, callback?: Callback): Promise; 15 | getEpic(opts: { 16 | epicId: number | string; 17 | }, callback?: Callback): Promise; 18 | partiallyUpdateEpic(opts: { 19 | epicId: number | string; 20 | name?: string; 21 | summary?: string; 22 | color?: any; 23 | done?: boolean; 24 | }, callback?: Callback): Promise; 25 | getIssuesForEpic(opts: { 26 | epicId: number | string; 27 | startAt?: number; 28 | maxResults?: number; 29 | jql?: string; 30 | validateQuery?: boolean; 31 | fields?: string[]; 32 | expand?: string; 33 | }, callback?: Callback): Promise; 34 | moveIssuesToEpic(opts: { 35 | epicId: number | string; 36 | issues?: string[]; 37 | }, callback?: Callback): Promise; 38 | rankEpics(opts: { 39 | epicId: number | string; 40 | rankBeforeEpic?: string; 41 | rankAfterEpic?: string; 42 | rankCustomFieldId?: number; 43 | }, callback?: Callback): Promise; 44 | } 45 | -------------------------------------------------------------------------------- /types/api/developmentInformation.d.ts: -------------------------------------------------------------------------------- 1 | import { Callback } from "../callback"; 2 | 3 | export class DevelopmentInformation { 4 | store( 5 | params: { 6 | Authorization: string, 7 | repositories: any[], 8 | preventTransitions?: boolean, 9 | properties?: any, 10 | providerMetadata?: any, 11 | }, 12 | callback?: Callback 13 | ): Promise; 14 | 15 | getRepository( 16 | params: { 17 | Authorization: string, 18 | repositoryId: string 19 | }, 20 | callback?: Callback 21 | ): Promise; 22 | 23 | deleteRepository( 24 | params: { 25 | Authorization: string, 26 | repositoryId: string, 27 | _updateSequenceId?: number 28 | }, 29 | callback?: Callback 30 | ): Promise; 31 | 32 | deleteByProperties( 33 | params: { 34 | Authorization: string, 35 | _updateSequenceId?: number 36 | }, 37 | callback?: Callback 38 | ): Promise; 39 | 40 | checkExists( 41 | params: { 42 | Authorization: string, 43 | _updateSequenceId?: number 44 | }, 45 | callback?: Callback 46 | ): Promise; 47 | 48 | deleteEntity( 49 | params: { 50 | Authorization: string, 51 | repositoryId: string, 52 | entityType: 'commit' | 'branch' | 'pull_request', 53 | entityId: string, 54 | _updateSequenceId?: number 55 | }, 56 | callback?: Callback 57 | ): Promise; 58 | } 59 | -------------------------------------------------------------------------------- /api/customFieldOption.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | 3 | var errorStrings = require('./../lib/error'); 4 | 5 | module.exports = CustomFieldOptionClient; 6 | 7 | /** 8 | * Used to access Jira REST endpoints in '/rest/api/2/customFieldOptions' 9 | * 10 | * @param {JiraClient} jiraClient 11 | * @constructor CustomFieldOptionClient 12 | */ 13 | function CustomFieldOptionClient(jiraClient) { 14 | this.jiraClient = jiraClient; 15 | 16 | /** 17 | * Returns a full representation of the Custom Field Option that has the given id. 18 | * 19 | * @method getCustomFieldOption 20 | * @memberOf CustomFieldOptionClient# 21 | * @param {Object} opts The request options sent to the Jira API 22 | * @param {string} opts.fieldOptionId A String containing an Custom Field Option id 23 | * @param [callback] Called when data has been retrieved 24 | * @return {Promise} Resolved when data has been retrieved 25 | */ 26 | this.getCustomFieldOption = function (opts, callback) { 27 | if (!opts.fieldOptionId) { 28 | throw new Error(errorStrings.NO_FIELD_OPTION_ID_ERROR); 29 | } 30 | 31 | var options = { 32 | uri: this.jiraClient.buildURL('/customFieldOption/' + opts.fieldOptionId), 33 | method: 'GET', 34 | json: true, 35 | followAllRedirects: true 36 | }; 37 | 38 | return this.jiraClient.makeRequest(options, callback); 39 | }; 40 | } -------------------------------------------------------------------------------- /api/projectValidate.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | 3 | module.exports = ProjectValidateClient; 4 | 5 | /** 6 | * Used to access Jira REST endpoints in '/rest/api/2/projectvalidate' 7 | * 8 | * @param {JiraClient} jiraClient 9 | * @constructor ProjectValidateClient 10 | */ 11 | function ProjectValidateClient(jiraClient) { 12 | this.jiraClient = jiraClient; 13 | 14 | /** 15 | * Validates a project key. This endpoint is a little wonky, as it returns a list of errors as a valid response; 16 | * even if the key is invalid, it still returns a 200 response. 17 | * See {@link https://docs.atlassian.com/jira/REST/latest/#d2e297} 18 | * 19 | * @method validateProjectKey 20 | * @memberOf ProjectValidateClient# 21 | * @param opts The request options sent to the Jira API. 22 | * @param opts.projectKey The key of the project. 23 | * @param [callback] Called when the key has been validated. 24 | * @return {Promise} Resolved when the key has been validated. 25 | */ 26 | this.validateProjectKey = function (opts, callback) { 27 | var options = { 28 | uri: this.jiraClient.buildURL('/projectvalidate/key'), 29 | method: 'GET', 30 | json: true, 31 | followAllRedirects: true, 32 | qs: { 33 | key: opts.projectKey 34 | } 35 | }; 36 | 37 | return this.jiraClient.makeRequest(options, callback); 38 | } 39 | } -------------------------------------------------------------------------------- /api/password.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | 3 | module.exports = PasswordClient; 4 | 5 | /** 6 | * Used to access Jira REST endpoints in '/rest/api/2/password' 7 | * 8 | * @param {JiraClient} jiraClient 9 | * @constructor PasswordClient 10 | */ 11 | function PasswordClient(jiraClient) { 12 | this.jiraClient = jiraClient; 13 | 14 | /** 15 | * Returns user-friendly statements governing the system's password policy. 16 | * 17 | * @method getPasswordPolicy 18 | * @memberOf PasswordClient# 19 | * @param opts The request options to send to the Jira API 20 | * @param {boolean} [opts.hasOldPassword=false] Whether or not the user will be required to enter their current 21 | * password. Use false (the default) if this is a new user or if an administrator is forcibly changing another 22 | * user's password. 23 | * @param [callback] Called when the password policy has been retrieved. 24 | * @return {Promise} Resolved when the password policy has been retrieved. 25 | */ 26 | this.getPasswordPolicy = function (opts, callback) { 27 | var options = { 28 | uri: this.jiraClient.buildURL('/password/policy'), 29 | method: 'GET', 30 | json: true, 31 | followAllRedirects: true, 32 | qs: { 33 | hasOldPassword: opts.hasOldPassword 34 | } 35 | }; 36 | 37 | return this.jiraClient.makeRequest(options, callback); 38 | } 39 | } -------------------------------------------------------------------------------- /types/models/temp.d.ts: -------------------------------------------------------------------------------- 1 | import { IssuesStatusForFixVersion, Operation } from "./version"; 2 | 3 | export interface Sprint { 4 | id: string; 5 | self: string; 6 | state: 'active' | 'closed' | 'future'; 7 | name: string; 8 | startDate: string; 9 | endDate: string; 10 | originBoardId: number; 11 | goal: string; 12 | completeDate?: string; 13 | } 14 | 15 | export interface PageBeanVersion { 16 | self: string; 17 | nextPage: string; 18 | maxResults: number; 19 | startAt: number; 20 | total: number; 21 | isLast: boolean; 22 | values: Value[]; 23 | } 24 | 25 | export interface Board { 26 | id: number; 27 | self: string; 28 | name: string; 29 | type: string; 30 | location: BoardLocation; 31 | } 32 | 33 | export interface BoardLocation { 34 | projectId: number; 35 | displayName: string; 36 | projectName: string; 37 | projectKey: string; 38 | projectTypeKey: string; 39 | avatarURI: string; 40 | name: string; 41 | } 42 | 43 | export interface Value { 44 | expand: string; 45 | self: string; 46 | id: string; 47 | description: string; 48 | name: string; 49 | archived: boolean; 50 | released: boolean; 51 | startDate: string; 52 | releaseDate: string; 53 | overdue: boolean; 54 | userStartDate: string; 55 | userReleaseDate: string; 56 | project: string; 57 | projectId: number; 58 | moveUnfixedIssuesTo: string; 59 | operations: Operation[]; 60 | issuesStatusForFixVersion: IssuesStatusForFixVersion; 61 | } 62 | -------------------------------------------------------------------------------- /api/status.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | 3 | module.exports = StatusClient; 4 | 5 | /** 6 | * Used to access Jira REST endpoints in '/rest/api/2/status' 7 | * 8 | * @param {JiraClient} jiraClient 9 | * @constructor StatusClient 10 | */ 11 | function StatusClient(jiraClient) { 12 | this.jiraClient = jiraClient; 13 | 14 | /** 15 | * Returns a list of all statuses visible to the user 16 | * 17 | * @method getAllStatuses 18 | * @memberOf StatusClient# 19 | * @param opts Ignored 20 | * @param [callback] Called when statuses have been retrieved. 21 | * @return {Promise} Resolved when statuses have been retrieved. 22 | */ 23 | this.getAllStatuses = function (opts, callback) { 24 | var options = { 25 | uri: this.jiraClient.buildURL('/status'), 26 | method: 'GET', 27 | json: true, 28 | followAllRedirects: true 29 | }; 30 | 31 | return this.jiraClient.makeRequest(options, callback); 32 | }; 33 | 34 | /** 35 | * Get a full representation of the status that has the given id. 36 | * 37 | * @method getStatus 38 | * @memberOf StatusClient# 39 | * @param opts The options sent to the Jira API 40 | * @param opts.statusId A String containing a status id 41 | * @param [callback] Called when the status has been retrieved. 42 | * @return {Promise} Resolved when the status has been retrieved. 43 | */ 44 | this.getStatus = function (opts, callback) { 45 | var options = { 46 | uri: this.jiraClient.buildURL('/status/' + opts.statusId), 47 | method: 'GET', 48 | json: true, 49 | followAllRedirects: true 50 | }; 51 | 52 | return this.jiraClient.makeRequest(options, callback); 53 | }; 54 | } -------------------------------------------------------------------------------- /api/priority.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | 3 | module.exports = PriorityClient; 4 | 5 | /** 6 | * Used to access Jira REST endpoints in '/rest/api/2/priority' 7 | * 8 | * @param {JiraClient} jiraClient 9 | * @constructor PriorityClient 10 | */ 11 | function PriorityClient(jiraClient) { 12 | this.jiraClient = jiraClient; 13 | 14 | /** 15 | * Returns a list of all priorities visible to the user 16 | * 17 | * @method getAllPriorities 18 | * @memberOf PriorityClient# 19 | * @param opts Ignored 20 | * @param [callback] Called when the priorities have been retrieved. 21 | * @return {Promise} Resolved when the priorities have been retrieved. 22 | */ 23 | this.getAllPriorities = function (opts, callback) { 24 | var options = { 25 | uri: this.jiraClient.buildURL('/priority'), 26 | method: 'GET', 27 | json: true, 28 | followAllRedirects: true 29 | }; 30 | 31 | return this.jiraClient.makeRequest(options, callback); 32 | }; 33 | 34 | /** 35 | * Get a full representation of the priority that has the given id. 36 | * 37 | * @method getPriority 38 | * @memberOf PriorityClient# 39 | * @param opts The options sent to the Jira API 40 | * @param opts.priorityId A String containing a priority id 41 | * @param [callback] Called when the priority has been retrieved. 42 | * @return {Promise} Resolved when the priority has been retrieved. 43 | */ 44 | this.getPriority = function (opts, callback) { 45 | var options = { 46 | uri: this.jiraClient.buildURL('/priority/' + opts.priorityId), 47 | method: 'GET', 48 | json: true, 49 | followAllRedirects: true 50 | }; 51 | 52 | return this.jiraClient.makeRequest(options, callback); 53 | }; 54 | } -------------------------------------------------------------------------------- /api/settings.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | 3 | module.exports = SettingsClient; 4 | 5 | /** 6 | * Used to access Jira REST endpoints in '/rest/api/2/settings' 7 | * @param {JiraClient} jiraClient 8 | * @constructor SettingsClient 9 | */ 10 | function SettingsClient(jiraClient) { 11 | this.jiraClient = jiraClient; 12 | 13 | /** 14 | * Sets the base URL that is configured for this JIRA instance. 15 | * 16 | * @method setBaseUrl 17 | * @memberOf SettingsClient# 18 | * @param opts The request options sent to the Jira API. 19 | * @param opts.newUrl The new base url. 20 | * @param [callback] Called when the base url has been set. 21 | * @return {Promise} Resolved when the base url has been set. 22 | */ 23 | this.setBaseUrl = function (opts, callback) { 24 | var options = { 25 | uri: this.jiraClient.buildURL('/settings/baseUrl'), 26 | method: 'PUT', 27 | json: true, 28 | followAllRedirects: true, 29 | body: opts.newUrl 30 | }; 31 | 32 | return this.jiraClient.makeRequest(options, callback); 33 | }; 34 | 35 | /** 36 | * Returns the default system columns for issue navigator. Admin permission will be required. 37 | * 38 | * @method getIssueNavColumns 39 | * @memberOf SettingsClient# 40 | * @param opts Ignored 41 | * @param [callback] Called when the columns have been retrieved 42 | * @return {Promise} Resolved when the columns have been retrieved 43 | */ 44 | this.getIssueNavColumns = function (opts, callback) { 45 | var options = { 46 | uri: this.jiraClient.buildURL('/settings/columns'), 47 | method: 'GET', 48 | json: true, 49 | followAllRedirects: true 50 | }; 51 | 52 | return this.jiraClient.makeRequest(options, callback); 53 | }; 54 | } -------------------------------------------------------------------------------- /api/field.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | 3 | module.exports = FieldClient; 4 | 5 | /** 6 | * Used to access Jira REST endpoints in '/rest/api/2/field' 7 | * 8 | * @param {JiraClient} jiraClient 9 | * @constructor FieldClient 10 | */ 11 | function FieldClient(jiraClient) { 12 | this.jiraClient = jiraClient; 13 | 14 | /** 15 | * Returns a list of all fields, both System and Custom 16 | * 17 | * @method getAllFields 18 | * @memberOf FieldClient# 19 | * @param opts Ignored 20 | * @param [callback] Called when the fields have been retrieved. 21 | * @return {Promise} Resolved when the fields have been retrieved. 22 | */ 23 | this.getAllFields = function (opts, callback) { 24 | var options = { 25 | uri: this.jiraClient.buildURL('/field'), 26 | method: 'GET', 27 | json: true, 28 | followAllRedirects: true 29 | }; 30 | 31 | return this.jiraClient.makeRequest(options, callback); 32 | }; 33 | 34 | /** 35 | * Creates a custom field using a definition (object encapsulating custom field data) 36 | * 37 | * @method createCustomField 38 | * @memberOf FieldClient# 39 | * @param opts The request options to send to Jira 40 | * @param opts.field See {@link https://docs.atlassian.com/jira/REST/latest/#d2e3412} 41 | * @param [callback] Called when the custom field has been created. 42 | * @return {Promise} Resolved when the custom field has been created. 43 | */ 44 | this.createCustomField = function (opts, callback) { 45 | var options = { 46 | uri: this.jiraClient.buildURL('/field'), 47 | method: 'POST', 48 | json: true, 49 | followAllRedirects: true, 50 | body: opts.field 51 | }; 52 | 53 | return this.jiraClient.makeRequest(options, callback); 54 | } 55 | } -------------------------------------------------------------------------------- /api/resolution.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | 3 | module.exports = ResolutionClient; 4 | 5 | /** 6 | * Used to access Jira REST endpoints in '/rest/api/2/resolution' 7 | * 8 | * @param {JiraClient} jiraClient 9 | * @constructor ResolutionClient 10 | */ 11 | function ResolutionClient(jiraClient) { 12 | this.jiraClient = jiraClient; 13 | 14 | /** 15 | * Returns a list of all resolutions visible to the user 16 | * 17 | * @method getAllResolutions 18 | * @memberOf ResolutionClient# 19 | * @param opts Ignored 20 | * @param [callback] Called when the resolutions have been retrieved. 21 | * @return {Promise} Resolved when the resolutions have been retrieved. 22 | */ 23 | this.getAllResolutions = function (opts, callback) { 24 | var options = { 25 | uri: this.jiraClient.buildURL('/resolution'), 26 | method: 'GET', 27 | json: true, 28 | followAllRedirects: true 29 | }; 30 | 31 | return this.jiraClient.makeRequest(options, callback); 32 | }; 33 | 34 | /** 35 | * Get a full representation of the resolution that has the given id. 36 | * 37 | * @method getResolution 38 | * @memberOf ResolutionClient# 39 | * @param opts The options sent to the Jira API 40 | * @param opts.resolutionId A String containing a resolution id 41 | * @param [callback] Called when the resolution has been retrieved. 42 | * @return {Promise} Resolved when the resolution has been retrieved. 43 | */ 44 | this.getResolution = function (opts, callback) { 45 | var options = { 46 | uri: this.jiraClient.buildURL('/resolution/' + opts.resolutionId), 47 | method: 'GET', 48 | json: true, 49 | followAllRedirects: true 50 | }; 51 | 52 | return this.jiraClient.makeRequest(options, callback); 53 | }; 54 | } -------------------------------------------------------------------------------- /api/groups.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | 3 | module.exports = GroupsClient; 4 | 5 | /** 6 | * Used to access Jira REST endpoints in '/rest/api/2/groups' 7 | * 8 | * @param {JiraClient} jiraClient 9 | * @constructor GroupsClient 10 | */ 11 | function GroupsClient(jiraClient) { 12 | this.jiraClient = jiraClient; 13 | 14 | /** 15 | * Returns groups with substrings matching a given query. This is mainly for use with the group picker, so the 16 | * returned groups contain html to be used as picker suggestions. The groups are also wrapped in a single response 17 | * object that also contains a header for use in the picker, specifically Showing X of Y matching groups. The 18 | * number of groups returned is limited by the system property "jira.ajax.autocomplete.limit" The groups will be 19 | * unique and sorted. 20 | * 21 | * @method findGroups 22 | * @memberOf GroupsClient# 23 | * @param {Object} opts The request options to use in the Jira API. 24 | * @param {string} opts.query A string against which to match groups. Leave this blank to return all groups. 25 | * @param {string} opts.exclude A string specifying groups to exclude. 26 | * @param {number} opts.maxResults The maximum number of results to return. 27 | * @param [callback] Called when the groups have been retrieved. 28 | * @return {Promise} Resolved when the groups have been retrieved. 29 | */ 30 | this.findGroups = function (opts, callback) { 31 | var options = { 32 | uri: this.jiraClient.buildURL('/groups/picker'), 33 | method: 'GET', 34 | json: true, 35 | followAllRedirects: true, 36 | qs: { 37 | query: opts.query, 38 | exclude: opts.exclude, 39 | maxResults: opts.maxResults 40 | } 41 | }; 42 | 43 | return this.jiraClient.makeRequest(options, callback); 44 | } 45 | } -------------------------------------------------------------------------------- /types/api/sprint.d.ts: -------------------------------------------------------------------------------- 1 | import { Callback } from "../callback"; 2 | import { Sprint as SprintModel } from "../models"; 3 | 4 | export type SprintId = string | number; 5 | 6 | export class Sprint { 7 | createSprint( 8 | sprint: Pick< 9 | SprintModel, 10 | | 'name' // 11 | | 'startDate' 12 | | 'endDate' 13 | | 'originBoardId' 14 | | 'goal' 15 | >, 16 | callback?: Callback 17 | ): Promise; 18 | getSprint( 19 | opts: { 20 | sprintId: SprintId; 21 | filter?: number; 22 | startAt?: number; 23 | maxResults?: number; 24 | }, 25 | callback?: Callback 26 | ): Promise; 27 | updateSprint( 28 | opts: { sprintId: SprintId } & Partial, 29 | callback?: Callback 30 | ): Promise; 31 | partiallyUpdateSprint( 32 | opts: { sprintId: SprintId } & Partial, 33 | callback?: Callback 34 | ): Promise; 35 | deleteSprint( 36 | opts: { 37 | sprintId: SprintId; 38 | filter?: number; 39 | startAt?: number; 40 | maxResults?: number; 41 | }, 42 | callback?: Callback 43 | ): Promise; 44 | getSprintIssues( 45 | opts: { 46 | sprintId: SprintId; 47 | startAt?: number; 48 | maxResults?: number; 49 | jql?: string; 50 | validateQuery?: boolean; 51 | fields?: string[]; 52 | expand?: string; 53 | }, 54 | callback?: Callback 55 | ): Promise; 56 | moveSprintIssues( 57 | opts: { 58 | sprintId: SprintId; 59 | issues: string[]; 60 | rankBeforeIssue?: string; 61 | rankAfterIssue?: string; 62 | rankCustomFieldId?: string; 63 | }, 64 | callback?: Callback 65 | ): Promise; 66 | swapSprint( 67 | opts: { 68 | sprintId: SprintId; 69 | sprintToSwapWith: string; 70 | }, 71 | callback?: Callback 72 | ): Promise; 73 | } 74 | -------------------------------------------------------------------------------- /api/statusCategory.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | 3 | module.exports = StatusCategoryClient; 4 | 5 | /** 6 | * Used to access Jira REST endpoints in '/rest/api/2/statuscategory' 7 | * 8 | * @param {JiraClient} jiraClient 9 | * @constructor StatusCategoryClient 10 | */ 11 | function StatusCategoryClient(jiraClient) { 12 | this.jiraClient = jiraClient; 13 | 14 | /** 15 | * Returns a list of all statusCategories visible to the user 16 | * 17 | * @method getAllStatusCategories 18 | * @memberOf StatusCategoryClient# 19 | * @param opts Ignored 20 | * @param [callback] Called when the statusCategories have been retrieved. 21 | * @return {Promise} Resolved when the statusCategories have been retrieved. 22 | */ 23 | this.getAllStatusCategories = function (opts, callback) { 24 | var options = { 25 | uri: this.jiraClient.buildURL('/statuscategory'), 26 | method: 'GET', 27 | json: true, 28 | followAllRedirects: true 29 | }; 30 | 31 | return this.jiraClient.makeRequest(options, callback); 32 | }; 33 | 34 | /** 35 | * Get a full representation of the statusCategory that has the given id or key. 36 | * 37 | * @method getStatusCategory 38 | * @memberOf StatusCategoryClient# 39 | * @param opts The options sent to the Jira API 40 | * @param opts.statusCategoryIdOrKey A String containing a statusCategory id 41 | * @param [callback] Called when the statusCategory has been retrieved. 42 | * @return {Promise} Resolved when the statusCategory has been retrieved. 43 | */ 44 | this.getStatusCategory = function (opts, callback) { 45 | var options = { 46 | uri: this.jiraClient.buildURL('/statuscategory/' + opts.statusCategoryIdOrKey), 47 | method: 'GET', 48 | json: true, 49 | followAllRedirects: true 50 | }; 51 | 52 | return this.jiraClient.makeRequest(options, callback); 53 | }; 54 | } -------------------------------------------------------------------------------- /api/projectCategory.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | 3 | module.exports = ProjectCategoryClient; 4 | 5 | /** 6 | * Used to access Jira REST endpoints in '/rest/api/2/projectCategory' 7 | * 8 | * @param {JiraClient} jiraClient 9 | * @constructor ProjectCategoryClient 10 | */ 11 | function ProjectCategoryClient(jiraClient) { 12 | this.jiraClient = jiraClient; 13 | 14 | /** 15 | * Returns a list of all projectCategories visible to the user 16 | * 17 | * @method getAllProjectCategories 18 | * @memberOf ProjectCategoryClient# 19 | * @param opts Ignored 20 | * @param [callback] Called when the statusCategories have been retrieved. 21 | * @return {Promise} Resolved when the statusCategories have been retrieved. 22 | */ 23 | this.getAllProjectCategories = function (opts, callback) { 24 | var options = { 25 | uri: this.jiraClient.buildURL('/projectCategory'), 26 | method: 'GET', 27 | json: true, 28 | followAllRedirects: true 29 | }; 30 | 31 | return this.jiraClient.makeRequest(options, callback); 32 | }; 33 | 34 | /** 35 | * Get a full representation of the projectCategory that has the given id. 36 | * 37 | * @method getProjectCategory 38 | * @memberOf ProjectCategoryClient# 39 | * @param opts The options sent to the Jira API 40 | * @param opts.projectCategoryId A String containing a projectCategory id 41 | * @param [callback] Called when the projectCategory has been retrieved. 42 | * @return {Promise} Resolved when the projectCategory has been retrieved. 43 | */ 44 | this.getProjectCategory = function (opts, callback) { 45 | var options = { 46 | uri: this.jiraClient.buildURL('/projectCategory/' + opts.projectCategoryId), 47 | method: 'GET', 48 | json: true, 49 | followAllRedirects: true 50 | }; 51 | 52 | return this.jiraClient.makeRequest(options, callback); 53 | }; 54 | } 55 | -------------------------------------------------------------------------------- /types/api/version.d.ts: -------------------------------------------------------------------------------- 1 | import { Callback } from "../callback"; 2 | import { Version as VersionModel } from "../models"; 3 | 4 | export class Version { 5 | createVersion( 6 | opts: { 7 | expand?: string; 8 | description?: string; 9 | name?: string; 10 | archived?: boolean; 11 | released?: boolean; 12 | startDate?: string; 13 | releaseDate?: string; 14 | project?: string; 15 | projectId?: number; 16 | moveUnfixedIssuesTo?: string; 17 | }, 18 | callback?: Callback 19 | ): Promise; 20 | 21 | moveVersion( 22 | opts: { 23 | versionId: string; 24 | after?: string; 25 | position?: string; 26 | }, 27 | callback?: Callback 28 | ): Promise; 29 | 30 | getAllVersions( 31 | opts: any, 32 | callback?: Callback 33 | ): Promise; 34 | 35 | getVersion( 36 | opts: any, 37 | callback?: Callback 38 | ): Promise; 39 | 40 | editVersion( 41 | opts: any, 42 | callback?: Callback 43 | ): Promise; 44 | 45 | getRelatedIssueCounts( 46 | opts: any, 47 | callback?: Callback 48 | ): Promise; 49 | 50 | getUnresolvedIssueCount( 51 | opts: any, 52 | callback?: Callback 53 | ): Promise; 54 | 55 | getRemoteLinks( 56 | opts: any, 57 | callback?: Callback 58 | ): Promise; 59 | 60 | createRemoteLink( 61 | opts: any, 62 | callback?: Callback 63 | ): Promise; 64 | 65 | getRemoteLink( 66 | opts: any, 67 | callback?: Callback 68 | ): Promise; 69 | 70 | deleteRemoteLink( 71 | opts: any, 72 | callback?: Callback 73 | ): Promise; 74 | 75 | deleteVersion( 76 | opts: any, 77 | callback?: Callback 78 | ): Promise; 79 | 80 | deleteAllRemoteLinks( 81 | opts: any, 82 | callback?: Callback 83 | ): Promise; 84 | 85 | getGlobalRemoteLink( 86 | opts: any, 87 | callback?: Callback 88 | ): Promise; 89 | } 90 | -------------------------------------------------------------------------------- /types/api/project.d.ts: -------------------------------------------------------------------------------- 1 | import { Callback } from "../callback"; 2 | import { PageBeanVersion } from "../models"; 3 | 4 | export class Project { 5 | getAllProjects( 6 | opts?: { 7 | expand?: string; 8 | recent?: number; 9 | properties?: string[]; 10 | apiVersion?: string | number | 2 | 3; 11 | }, 12 | callback?: Callback 13 | ): Promise; 14 | 15 | updateProject( 16 | opts: { 17 | projectIdOrKey: string | number; 18 | expand?: string; 19 | key?: string; 20 | name?: string; 21 | projectTypeKey?: string; 22 | projectTemplateKey?: string; 23 | description?: string; 24 | lead?: string; 25 | leadAccountId?: string; 26 | url?: string; 27 | assigneeType?: string; 28 | avatarId?: number; 29 | issueSecurityScheme?: number; 30 | permissionScheme?: number; 31 | notificationScheme?: number; 32 | categoryId?: number; 33 | }, 34 | callback?: Callback 35 | ): Promise; 36 | 37 | deleteProject( 38 | opts: { projectIdOrKey: string | number }, 39 | callback?: Callback 40 | ): Promise; 41 | 42 | createProject(opts?: any, callback?: Callback): Promise; 43 | 44 | getProjectProperties(opts: any, callback?: Callback): Promise; 45 | 46 | getProject(opts: any, callback?: Callback): Promise; 47 | 48 | getComponents(opts: any, callback?: Callback): Promise; 49 | 50 | getStatuses(opts: any, callback?: Callback): Promise; 51 | 52 | getVersions(opts: any, callback?: Callback): Promise; 53 | 54 | getVersionsPaginated(opts: { 55 | projectIdOrKey: string; 56 | startAt?: number; 57 | maxResults?: number; 58 | orderBy?: string; 59 | query?: string; 60 | status?: string; 61 | expand?: any[]; 62 | }, callback?: Callback): Promise; 63 | 64 | getRoles(opts: any, callback?: Callback): Promise; 65 | 66 | getRole(opts: any, callback?: Callback): Promise; 67 | 68 | updateRole(opts: any, callback?: Callback): Promise; 69 | 70 | addToRole(opts: any, callback?: Callback): Promise; 71 | } 72 | -------------------------------------------------------------------------------- /api/labels.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | module.exports = LabelsClient; 4 | 5 | /** 6 | * Used to access Jira REST endpoints in '/rest/api/1.0/labels' and '/rest/api/2/label' 7 | * @param {JiraClient} jiraClient 8 | * @constructor LabelsClient 9 | */ 10 | function LabelsClient(jiraClient) { 11 | this.jiraClient = jiraClient; 12 | 13 | /** 14 | * Use this method to retrieve all the available labels 15 | * e.g if you create an issue and you have to fill the labels field, use this method to get all the available values 16 | * 17 | * @method getLabels 18 | * @memberOf LabelsClient# 19 | * @param {Object} opts The request options sent to the Jira API. 20 | * @param {string} opts.query Used for filter labels 21 | * @param {callback} [callback] Called when labels are retrieved 22 | * @return {Promise} Resolved when labels are retrieved 23 | */ 24 | this.getLabels = function (opts, callback) { 25 | var options = { 26 | uri: this.jiraClient.buildURL('/labels/suggest?query=' + opts.query, '1.0'), 27 | method: 'GET', 28 | json: true, 29 | followAllRedirects: true 30 | }; 31 | 32 | return this.jiraClient.makeRequest(options, callback); 33 | }; 34 | 35 | /** 36 | * Returns a paginated list of labels. 37 | * 38 | * @method getAllLabels 39 | * @memberOf LabelsClient# 40 | * @param {Object} [opts] 41 | * @param {number} [opts.startAt] The index of the first item to return in a page of results (page offset). 42 | * @param {number} [opts.maxResults] The maximum number of items to return per page. 43 | * @param {callback} [callback] Called when labels are retrieved 44 | * @return {Promise} Resolved when labels are retrieved 45 | */ 46 | this.getAllLabels = function (opts, callback) { 47 | opts = opts || {}; 48 | 49 | var options = { 50 | uri: this.jiraClient.buildURL('/label'), 51 | method: 'GET', 52 | json: true, 53 | followAllRedirects: true, 54 | qs: { 55 | startAt: opts.startAt, 56 | maxResults: opts.maxResults, 57 | } 58 | }; 59 | 60 | return this.jiraClient.makeRequest(options, callback); 61 | }; 62 | } 63 | -------------------------------------------------------------------------------- /types/api/user.d.ts: -------------------------------------------------------------------------------- 1 | import { Callback } from "../callback"; 2 | 3 | export interface UserInfo { 4 | self: string; 5 | key: string; 6 | accountId: string; 7 | name: string; 8 | emailAddress: string; 9 | avatarUrls: AvatarUrls; 10 | displayName: string; 11 | active: boolean; 12 | timeZone: string; 13 | groups: ApplicationRoles; 14 | applicationRoles: ApplicationRoles; 15 | } 16 | 17 | export interface ApplicationRoles { 18 | size: number; 19 | items: any[]; 20 | } 21 | 22 | export interface AvatarUrls { 23 | "48x48": string; 24 | "24x24": string; 25 | "16x16": string; 26 | "32x32": string; 27 | } 28 | 29 | export class User { 30 | getUser( 31 | opts: { 32 | accountId?: string; 33 | username?: string; 34 | userKey?: string; 35 | expand?: string; 36 | }, 37 | callback?: Callback, 38 | ): Promise; 39 | 40 | deleteUser(opts: any, callback?: Callback): Promise; 41 | createUser(opts: any, callback?: Callback): Promise; 42 | editUser(opts: any, callback?: Callback): Promise; 43 | multiProjectSearchAssignable(opts: any, callback?: Callback): Promise; 44 | searchAssignable(opts: any, callback?: Callback): Promise; 45 | createTemporaryAvatar(opts: any, callback?: Callback): Promise; 46 | convertTemporaryAvatar(opts: any, callback?: Callback): Promise; 47 | deleteAvatar(opts: any, callback?: Callback): Promise; 48 | getAvatars(opts: any, callback?: Callback): Promise; 49 | getDefaultColumns(opts: any, callback?: Callback): Promise; 50 | setDefaultColumns(opts: any, callback?: Callback): Promise; 51 | resetDefaultColumns(opts: any, callback?: Callback): Promise; 52 | changePassword(opts: any, callback?: Callback): Promise; 53 | searchPermissions(opts: any, callback?: Callback): Promise; 54 | searchPicker(opts: any, callback?: Callback): Promise; 55 | search(opts: any, callback?: Callback): Promise; 56 | 57 | all(opts: { 58 | startAt?: number, 59 | maxResults?: number 60 | }, callback?: Callback): Promise; 61 | 62 | viewIssueSearch(opts: any, callback?: Callback): Promise; 63 | } 64 | -------------------------------------------------------------------------------- /types/index.d.ts: -------------------------------------------------------------------------------- 1 | import { Callback } from './callback'; 2 | import { Config } from './config'; 3 | import { CoreOptions } from 'request'; 4 | import { 5 | ApplicationProperties, 6 | Attachment, 7 | Auditing, 8 | Auth, 9 | Avatar, 10 | Backlog, 11 | Board, 12 | DevelopmentInformation, 13 | Epic, 14 | Issue, 15 | IssueType, 16 | Labels, 17 | Project, 18 | Search, 19 | Sprint, 20 | User, 21 | Version, 22 | } from './api'; 23 | 24 | export * from './config'; 25 | export * from './callback'; 26 | export * from './models'; 27 | 28 | export default class JiraClient { 29 | constructor(config: Config); 30 | applicationProperties: ApplicationProperties; 31 | attachment: Attachment; 32 | auditing: Auditing; 33 | auth: Auth; 34 | avatar: Avatar; 35 | backlog: Backlog; 36 | board: Board; 37 | comment: any; 38 | component: any; 39 | customFieldOption: any; 40 | dashboard: any; 41 | developmentInformation: DevelopmentInformation; 42 | epic: Epic; 43 | field: any; 44 | filter: any; 45 | group: any; 46 | groupUserPicker: any; 47 | groups: any; 48 | issue: Issue; 49 | issueLink: any; 50 | issueLinkType: any; 51 | issueType: IssueType; 52 | jql: any; 53 | labels: Labels; 54 | licenseRole: any; 55 | licenseValidator: any; 56 | myPermissions: any; 57 | myPreferences: any; 58 | myself: any; 59 | password: any; 60 | permissions: any; 61 | permissionScheme: any; 62 | priority: any; 63 | project: Project; 64 | projectCategory: any; 65 | projectValidate: any; 66 | reindex: any; 67 | resolution: any; 68 | roles: any; 69 | screens: any; 70 | search: Search; 71 | securityLevel: any; 72 | serverInfo: any; 73 | settings: any; 74 | sprint: Sprint; 75 | status: any; 76 | statusCategory: any; 77 | user: User; 78 | version: Version; 79 | webhook: any; 80 | workflow: any; 81 | workflowScheme: any; 82 | worklog: any; 83 | 84 | buildAbstractURL(path: string): string; 85 | buildAgileURL(path: string, forcedVersion?: number | string): string; 86 | buildAuthURL(path: string, forcedVersion?: number | string): string; 87 | buildURL(path: string, forcedVersion?: number | string): string; 88 | buildWebhookURL(path: string, forcedVersion?: number | string): string; 89 | makeRequest(options: CoreOptions, callback?: Callback, successString?: string): Promise; 90 | 91 | static oauth_util: { 92 | getAuthorizeURL(config: any, callback: any): any, 93 | swapRequestTokenWithAccessToken(config: any, callback: any): void; 94 | }; 95 | } 96 | -------------------------------------------------------------------------------- /api/auth.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | 3 | var fs = require('fs'); 4 | var path = require('path'); 5 | 6 | module.exports = AuthClient; 7 | 8 | /** 9 | * Used to access Jira REST endpoints in '/rest/auth/1/session' 10 | * 11 | * @param {JiraClient} jiraClient 12 | * @constructor UserClient 13 | */ 14 | function AuthClient(jiraClient) { 15 | this.jiraClient = jiraClient; 16 | 17 | /** 18 | * Logs the current user out of JIRA, destroying the existing session, if any. 19 | * 20 | * @method logout 21 | * @memberOf Auth# 22 | * @param [callback] Called when the user has been logged out. 23 | * @return {Promise} Resolved when the user has been logged out. 24 | */ 25 | this.logout = function (callback) { 26 | var options = { 27 | uri: this.jiraClient.buildAuthURL('/session'), 28 | method: 'DELETE', 29 | json: true, 30 | followAllRedirects: true 31 | }; 32 | 33 | return this.jiraClient.makeRequest(options, callback, 'User logged out.'); 34 | }; 35 | 36 | /** 37 | * Creates a new session for a user in JIRA. 38 | * 39 | * @method login 40 | * @memberOf Auth# 41 | * @param opts The request options sent to the Jira API 42 | * @param opts.username The name of the user to login. 43 | * @param opts.password The password of the user. 44 | * @param [callback] Called when the user has been logged in. 45 | * @return {Promise} Resolved when the user has been logged in. 46 | */ 47 | this.login = function (opts, callback) { 48 | var options = { 49 | uri: this.jiraClient.buildAuthURL('/session'), 50 | method: 'POST', 51 | json: true, 52 | followAllRedirects: true, 53 | body: opts 54 | }; 55 | 56 | return this.jiraClient.makeRequest(options, callback, 'User logged in.'); 57 | }; 58 | 59 | /** 60 | * Get current User. Returns information about the currently authenticated user's session. 61 | * 62 | * @method currentUser 63 | * @memberOf Auth# 64 | * @param [callback] Called when the current user has been retrieved. 65 | * @return {Promise} Resolved when the user has been retrieved. 66 | */ 67 | this.currentUser = function (callback) { 68 | var options = { 69 | uri: this.jiraClient.buildAuthURL('/session'), 70 | method: 'GET', 71 | json: true, 72 | followAllRedirects: true, 73 | }; 74 | 75 | return this.jiraClient.makeRequest(options, callback); 76 | }; 77 | } 78 | -------------------------------------------------------------------------------- /lib/error.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | 3 | exports.NO_HOST_ERROR = 'Missing \'host\' property.'; 4 | exports.NO_CONSUMER_KEY_ERROR = 'Missing \'oauth_consumer_key\' property.'; 5 | exports.NO_PRIVATE_KEY_ERROR = 'Missing \'oauth_private_key\' property.'; 6 | exports.NO_OAUTH_TOKEN_ERROR = 'Missing \'oauth_token\' property.'; 7 | exports.NO_OAUTH_TOKEN_SECRET_ERROR = 'Missing \'oauth_token_secret\' property.'; 8 | exports.NO_USERNAME_ERROR = 'Missing \'username\' property.'; 9 | exports.NO_PASSWORD_ERROR = 'Missing \'password\' property.'; 10 | exports.NO_EMAIL_ERROR = 'Missing \'email\' property.'; 11 | exports.NO_APITOKEN_ERROR = 'Missing \'api_token\' property.'; 12 | exports.NO_AUTHENTICATION_ERROR = 'Missing \'auth\' property.'; 13 | exports.NO_JWT_SECRET_KEY_ERROR = 'Missing \'jwt_secret\' property.'; 14 | exports.NO_JWT_ISS_KEY_ERROR = 'Missing \'jwt_iss\' property.'; 15 | exports.NO_VERIFIER_ERROR = 'Missing \'oauth_verifier\' property.'; 16 | exports.INVALID_AUTHENTICATION_PROPERTY_ERROR = 'Invalid \'auth\' property.'; 17 | exports.NO_ISSUE_IDENTIFIER = 'Missing Issue ID or Key'; 18 | exports.NO_COMMENT_ID = 'Missing \'commentID\' property.'; 19 | exports.NO_COMMENT_ERROR = 'Missing \'comment\' property.'; 20 | exports.NO_NOTIFICATION_ERROR = 'Missing \'notification\' property'; 21 | exports.NO_GLOBAL_ID_ERROR = 'Missing \'globalId\' property.'; 22 | exports.NO_LINK_ID_ERROR = 'Missing \'linkId\' property.'; 23 | exports.NO_TRANSITION_ERROR = 'Missing \'transition\' property.'; 24 | exports.NO_ISSUE_ERROR = 'Missing \'issue\' property'; 25 | exports.NO_ASSIGNEE_ERROR = 'Missing \'assignee\' property'; 26 | exports.NO_WATCHER_ERROR = 'Missing \'watcher\' property'; 27 | exports.NO_WORKLOG_ERROR = 'Missing \'worklog\' property'; 28 | exports.NO_WORKLOG_ID_ERROR = 'Missing \'worklogId\' property'; 29 | exports.NO_FILENAME_ERROR = 'Missing \'filename\' property'; 30 | exports.NO_PROPERTY_KEY_ERROR = 'Missing \'propertyKey\' property'; 31 | exports.NO_PROPERTY_VALUE_ERROR = 'Missing \'propertyValue\' property'; 32 | exports.NO_ATTACHMENT_ID_ERROR = 'Missing \'attachmentId\' property'; 33 | exports.NO_AUDIT_ERROR = 'Missing \'audit\' property'; 34 | exports.NO_AVATAR_TYPE_ERROR = 'Missing \'avatarType\' property'; 35 | exports.NO_COMMENT_PROPERTY_KEY_ERROR = 'Missing \'propertyKey\' property'; 36 | exports.NO_COMMENT_PROPERTY_VALUE_ERROR = 'Missing \'propertyValue\' property'; 37 | exports.NO_ISSUE_LINK_ERROR = 'Missing\'issueLink\' property'; 38 | exports.NO_ISSUE_LINK_ID_ERROR = 'Missing\'linkId\' property'; 39 | exports.NO_ISSUE_LINK_TYPE_ID = 'Missing \'issueLinkTypeId\' property.'; 40 | exports.NO_FIELD_OPTION_ID_ERROR = 'Missing \'fieldOptionId\' property.'; 41 | -------------------------------------------------------------------------------- /api/myPermissions.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | 3 | module.exports = MyPermissionsClient; 4 | 5 | /** 6 | * Used to access Jira REST endpoints in '/rest/api/2/mypermissions' 7 | * 8 | * @param {JiraClient} jiraClient 9 | * @constructor MyPermissionsClient 10 | */ 11 | function MyPermissionsClient(jiraClient) { 12 | this.jiraClient = jiraClient; 13 | 14 | /** 15 | * Returns all permissions in the system and whether the currently logged in user has them. You can optionally 16 | * provide a specific context to get permissions for (projectKey OR projectId OR issueKey OR issueId) 17 | * 18 | * * When no context supplied the project related permissions will return true if the user has that permission in 19 | * ANY project 20 | * * If a project context is provided, project related permissions will return true if the user has the permissions 21 | * in the specified project. For permissions that are determined using issue data (e.g Current Assignee), true will 22 | * be returned if the user meets the permission criteria in ANY issue in that project 23 | * * If an issue context is provided, it will return whether or not the user has each permission in that specific 24 | * issue 25 | * 26 | * NB: The above means that for issue-level permissions (EDIT_ISSUE for example), hasPermission may be true when no 27 | * context is provided, or when a project context is provided, but may be false for any given (or all) issues. This 28 | * would occur (for example) if Reporters were given the EDIT_ISSUE permission. This is because any user could be a 29 | * reporter, except in the context of a concrete issue, where the reporter is known. 30 | * 31 | * Global permissions will still be returned for all scopes. 32 | * 33 | * @method getMyPermissions 34 | * @memberOf MyPermissionsClient# 35 | * @param opts The request options sent to the Jira API 36 | * @param [callback] Called when the permissions have been returned. 37 | * @return {Promise} Resolved when the permissions have been returned. 38 | */ 39 | this.getMyPermissions = function (opts, callback) { 40 | var options = { 41 | uri: this.jiraClient.buildURL('/mypermissions'), 42 | method: 'GET', 43 | json: true, 44 | followAllRedirects: true, 45 | qs: { 46 | issueId: opts.issueId, 47 | issueKey: opts.issueKey, 48 | projectId: opts.projectId, 49 | projectKey: opts.projectKey, 50 | }, 51 | }; 52 | 53 | return this.jiraClient.makeRequest(options, callback); 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /api/groupUserPicker.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | 3 | module.exports = GroupUserPickerClient; 4 | 5 | /** 6 | * Used to access Jira REST endpoints in '/rest/api/2/groupuserpicker' 7 | * @param {JiraClient} jiraClient 8 | * @constructor GroupUserPickerClient 9 | */ 10 | function GroupUserPickerClient(jiraClient) { 11 | this.jiraClient = jiraClient; 12 | 13 | /** 14 | * Returns a list of users and groups matching query with highlighting. This resource cannot be accessed 15 | * anonymously. 16 | * 17 | * @method findUsersAndGroups 18 | * @memberOf GroupUserPickerClient# 19 | * @param {Object} opts The request options to send to the Jira API. 20 | * @param {string} opts.query A string used to search username, Name or e-mail address 21 | * @param {number} [opts.maxResults] the maximum number of users to return (defaults to 50). The maximum allowed 22 | * value is 1000. If you specify a value that is higher than this number, your search results will be 23 | * truncated. 24 | * @param {boolean} [opts.showAvatar] Whether to show the avatar 25 | * @param {string} [opts.fieldId] The custom field id, if this request comes from a custom field, such as a user 26 | * picker. Optional. 27 | * @param {string} [opts.projectId] The list of project ids to further restrict the search This parameter can occur 28 | * multiple times to pass in multiple project ids. Comma separated value is not supported. This parameter is 29 | * only used when fieldId is present. 30 | * @param {string} [opts.issueTypeId] The list of issue type ids to further restrict the search. This parameter can 31 | * occur multiple times to pass in multiple issue type ids. Comma separated value is not supported. Special 32 | * values such as -1 (all standard issue types), -2 (all subtask issue types) are supported. This parameter is 33 | * only used when fieldId is present. 34 | * @param [callback] Called when the search is completed. 35 | * @return {Promise} Resolved when the search is completed. 36 | */ 37 | this.findUsersAndGroups = function (opts, callback) { 38 | var options = { 39 | uri: this.jiraClient.buildURL('/groupuserpicker'), 40 | method: 'GET', 41 | json: true, 42 | followAllRedirects: true, 43 | qs: { 44 | query: opts.query, 45 | maxResults: opts.maxResults, 46 | showAvatar: opts.showAvatar, 47 | fieldId: opts.fieldId, 48 | projectId: opts.projectId, 49 | issueTypeId: opts.issueTypeId 50 | } 51 | }; 52 | 53 | return this.jiraClient.makeRequest(options, callback); 54 | }; 55 | } -------------------------------------------------------------------------------- /api/backlog.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | 3 | module.exports = AgileBacklogClient; 4 | 5 | /** 6 | * Used to access Jira REST endpoints in '/rest/agile/1.0/backlog' 7 | * @param {JiraClient} jiraClient 8 | * @constructor AgileBacklogClient 9 | */ 10 | function AgileBacklogClient(jiraClient) { 11 | this.jiraClient = jiraClient; 12 | 13 | /** 14 | * Move issues to the backlog. This operation is equivalent to remove future and active sprints from a given set of 15 | * issues. At most 50 issues may be moved at once. 16 | * 17 | * @method moveIssuesToBacklog 18 | * @memberOf AgileBacklogClient# 19 | * @param opts The request options sent to the Jira API. 20 | * @param [opts.issues] Array of strings with issues keys or ids 21 | * @param [callback] Called when the dashboard has been retrieved 22 | * @return {Promise} Resolved when the dashboard has been retrieved 23 | */ 24 | this.moveIssuesToBacklog = function (opts, callback) { 25 | opts = opts || {}; 26 | var options = { 27 | uri: this.jiraClient.buildAgileURL("/backlog/issue"), 28 | method: "POST", 29 | json: true, 30 | followAllRedirects: true, 31 | body: { 32 | issues: opts.issues 33 | } 34 | }; 35 | 36 | return this.jiraClient.makeRequest(options, callback); 37 | }; 38 | 39 | /** 40 | * Move issues to the backlog of a particular board (if they are already on that board). 41 | * This operation is equivalent to remove future and active sprints from a given set of issues if the board has sprints 42 | * If the board does not have sprints this will put the issues back into the backlog from the board. At most 50 issues 43 | * may be moved at once. 44 | * 45 | * @method moveIssuesToBacklogForBoard 46 | * @memberOf AgileBacklogClient# 47 | * @param opts The request options sent to the Jira API. 48 | * @param opts.boardId The agile board id. 49 | * @param [opts.issues] Array of strings with issues keys or ids 50 | * @param [opts.rankBeforeIssue] string 51 | * @param [opts.rankAfterIssue] string 52 | * @param [opts.rankCustomFieldId] int64 53 | * @param [callback] Called when the dashboard has been retrieved 54 | * @return {Promise} Resolved when the dashboard has been retrieved 55 | */ 56 | this.moveIssuesToBacklogForBoard = function (opts, callback) { 57 | var options = { 58 | uri: this.jiraClient.buildAgileURL("/backlog/" + opts.boardId + "/issue"), 59 | method: "POST", 60 | json: true, 61 | followAllRedirects: true, 62 | body: { 63 | issues: opts.issues, 64 | rankBeforeIssue: opts.rankBeforeIssue, 65 | rankAfterIssue: opts.rankAfterIssue, 66 | rankCustomFieldId: opts.rankCustomFieldId 67 | } 68 | }; 69 | 70 | return this.jiraClient.makeRequest(options, callback); 71 | }; 72 | } 73 | -------------------------------------------------------------------------------- /api/myself.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | 3 | module.exports = MyselfClient; 4 | 5 | /** 6 | * Used to access Jira REST endpoints in '/rest/api/2/myself' 7 | * 8 | * @param {JiraClient} jiraClient 9 | * @constructor MyselfClient 10 | */ 11 | function MyselfClient(jiraClient) { 12 | this.jiraClient = jiraClient; 13 | 14 | /** 15 | * Returns currently logged user. This resource cannot be accessed anonymously. 16 | * 17 | * @method getMyself 18 | * @memberOf MyselfClient# 19 | * @param opts Ignored 20 | * @param [callback] Called when the current user is retrieved. 21 | * @return {Promise} Resolved when the current user is retrieved. 22 | */ 23 | this.getMyself = function (debug, callback) { 24 | var options = { 25 | uri: this.jiraClient.buildURL('/myself'), 26 | method: 'GET', 27 | json: true, 28 | followAllRedirects: true, 29 | debug: debug, 30 | }; 31 | 32 | return this.jiraClient.makeRequest(options, callback); 33 | }; 34 | 35 | /** 36 | * Modify currently logged user. The "value" fields present will override the existing value. Fields skipped in 37 | * request will not be changed. Only email and display name can be change that way. 38 | * 39 | * @method editMyself 40 | * @memberOf MyselfClient# 41 | * @param opts The request options send to the Jira API. 42 | * @param opts.newData The new data. See {@link https://docs.atlassian.com/jira/REST/latest/#d2e1242} 43 | * @param [callback] Called when the user's data has been modified 44 | * @return {Promise} Resolved when the user's data has been modified 45 | */ 46 | this.editMyself = function (opts, callback) { 47 | var options = { 48 | uri: this.jiraClient.buildURL('/myself'), 49 | method: 'PUT', 50 | json: true, 51 | followAllRedirects: true, 52 | body: opts.newData 53 | }; 54 | 55 | return this.jiraClient.makeRequest(options, callback); 56 | }; 57 | 58 | /** 59 | * Modify caller password. 60 | * 61 | * @method changePassword 62 | * @memberOf MyselfClient# 63 | * @param opts The request options sent to the Jira API. 64 | * @param opts.newData The new data 65 | * @param [callback] Called when the password has been changed. 66 | * @return {Promise} Resolved when the password has been changed. 67 | */ 68 | this.changePassword = function (opts, callback) { 69 | var options = { 70 | uri: this.jiraClient.buildURL('/myself/password'), 71 | method: 'PUT', 72 | json: true, 73 | followAllRedirects: true, 74 | body: opts.newData 75 | }; 76 | 77 | return this.jiraClient.makeRequest(options, callback); 78 | } 79 | } 80 | -------------------------------------------------------------------------------- /api/dashboard.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | 3 | module.exports = DashboardClient; 4 | 5 | /** 6 | * Used to access Jira REST endpoints in '/rest/api/2/dashboard' 7 | * @param {JiraClient} jiraClient 8 | * @constructor DashboardClient 9 | */ 10 | function DashboardClient(jiraClient) { 11 | this.jiraClient = jiraClient; 12 | 13 | /** 14 | * Get a list of all dashboards, optionally filtering them. 15 | * 16 | * @method getAllDashboards 17 | * @memberOf DashboardClient# 18 | * @param [opts] The request options to send to the Jira API 19 | * @param [opts.filter] An optional filter that is applied to the list of dashboards. Valid values include 20 | * "favourite" for returning only favourite dashboards, and "my" for returning dashboards that are owned by the 21 | * calling user. 22 | * @param [opts.startAt] The index of the first dashboard to return (0-based). must be 0 or a multiple of 23 | * maxResults 24 | * @param [opts.maxResults] A hint as to the the maximum number of dashboards to return in each call. Note that the 25 | * JIRA server reserves the right to impose a maxResults limit that is lower than the value that a client 26 | * provides, dues to lack or resources or any other condition. When this happens, your results will be 27 | * truncated. Callers should always check the returned maxResults to determine the value that is effectively 28 | * being used. 29 | * @param [callback] Called when the dashboards have been retrieved. 30 | * @return {Promise} Resolved when the dashboards have been retrieved. 31 | */ 32 | this.getAllDashboards = function (opts, callback) { 33 | opts = opts || {}; 34 | 35 | var options = { 36 | uri: this.jiraClient.buildURL('/dashboard'), 37 | method: 'GET', 38 | json: true, 39 | followAllRedirects: true, 40 | qs: { 41 | filter: opts.filter, 42 | startAt: opts.startAt, 43 | maxResults: opts.maxResults 44 | } 45 | }; 46 | 47 | return this.jiraClient.makeRequest(options, callback); 48 | }; 49 | 50 | /** 51 | * Get a single dashboard. 52 | * 53 | * @method getDashboard 54 | * @memberOf DashboardClient# 55 | * @param opts The request options sent to the Jira API. 56 | * @param opts.dashboardId The dashboard id. 57 | * @param [callback] Called when the dashboard has been retrieved 58 | * @return {Promise} Resolved when the dashboard has been retrieved 59 | */ 60 | this.getDashboard = function (opts, callback) { 61 | var options = { 62 | uri: this.jiraClient.buildURL('/dashboard/' + opts.dashboardId), 63 | method: 'GET', 64 | json: true, 65 | followAllRedirects: true 66 | }; 67 | 68 | return this.jiraClient.makeRequest(options, callback); 69 | } 70 | } 71 | -------------------------------------------------------------------------------- /api/licenseRole.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | 3 | module.exports = LicenseRoleClient; 4 | 5 | /** 6 | * Used to access Jira REST endpoints in '/rest/api/2/licenserole' 7 | * @param {JiraClient} jiraClient 8 | * @constructor LicenseRoleClient 9 | */ 10 | function LicenseRoleClient(jiraClient) { 11 | this.jiraClient = jiraClient; 12 | 13 | /** 14 | * Returns all license roles in the system. 15 | * 16 | * @method getAllLicenseRoles 17 | * @memberOf LicenseRoleClient# 18 | * @param opts Ignored 19 | * @param [callback] Called when the license roles have been retrieved. 20 | * @return {Promise} Resolved when the license roles have been retrieved. 21 | */ 22 | this.getAllLicenseRoles = function (opts, callback) { 23 | var options = { 24 | uri: this.jiraClient.buildURL('/licenserole'), 25 | method: 'GET', 26 | json: true, 27 | followAllRedirects: true 28 | }; 29 | 30 | return this.jiraClient.makeRequest(options, callback); 31 | }; 32 | 33 | /** 34 | * Gets the passed license role if it exists. 35 | * 36 | * @method getLicenseRole 37 | * @memberOf LicenseRoleClient# 38 | * @param opts The request options sent to the Jira API. 39 | * @param opts.roleId The id of the license role to retrieve. 40 | * @param [callback] Called when the license role is retrieved. 41 | * @return {Promise} Resolved when the license role is retrieved. 42 | */ 43 | this.getLicenseRole = function (opts, callback) { 44 | var options = { 45 | uri: this.jiraClient.buildURL('/licenserole/' + opts.roleId), 46 | method: 'GET', 47 | json: true, 48 | followAllRedirects: true 49 | }; 50 | 51 | return this.jiraClient.makeRequest(options, callback); 52 | }; 53 | 54 | /** 55 | * Updates the license role with the passed data. Only the groups of the role may be updated. Requests to change 56 | * the id or the name of the role will be silently ignored. 57 | * 58 | * @method editLicenseRole 59 | * @memberOf LicenseRoleClient# 60 | * @param opts The request options sent to the Jira API. 61 | * @param opts.roleId The id of the license role to retrieve. 62 | * @param opts.role The new data to place in the role. See 63 | * {@link https://docs.atlassian.com/jira/REST/latest/#d2e365} 64 | * @param [callback] Called when the license role is edited. 65 | * @return {Promise} Resolved when the license role is edited. 66 | */ 67 | this.editLicenseRole = function (opts, callback) { 68 | var options = { 69 | uri: this.jiraClient.buildURL('/licenserole/' + opts.roleId), 70 | method: 'PUT', 71 | json: true, 72 | followAllRedirects: true, 73 | body: opts.role 74 | }; 75 | 76 | return this.jiraClient.makeRequest(options, callback); 77 | } 78 | } -------------------------------------------------------------------------------- /api/application-properties.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | 3 | module.exports = ApplicationPropertiesClient; 4 | 5 | /** 6 | * Used to access Jira REST endpoints in '/rest/api/2/application-properties' 7 | * @constructor ApplicationPropertiesClient 8 | * @param {JiraClient} jiraClient 9 | */ 10 | function ApplicationPropertiesClient(jiraClient) { 11 | this.jiraClient = jiraClient; 12 | 13 | /** 14 | * Gets an application property. 15 | * @method getProperties 16 | * @memberOf ApplicationPropertiesClient# 17 | * @param {Object} [opts] The options used to make the request. 18 | * @param {string} [opts.key] A String containing the property key. 19 | * @param {string} [opts.permissionLevel] When fetching a list specifies the permission level of all items in the list. 20 | * @param {string} [opts.keyFilter] When fetching a list allows the list to be filtered by the property's start of key e.g. 21 | * "jira.lf.*" whould fetch only those permissions that are editable and whose keys start with "jira.lf.". This 22 | * is a regex 23 | * @param {callback} [callback] Called when the properties are retrieved. 24 | * @return {Promise} Resolved when the properties are retrieved. 25 | */ 26 | this.getProperties = function (opts, callback) { 27 | var qs = {}; 28 | if (opts) { 29 | if (opts.key) { 30 | qs.key = opts.key; 31 | } 32 | if (opts.keyFilter) { 33 | qs.keyFilter = opts.keyFilter; 34 | } 35 | if (opts.permissionLevel) { 36 | qs.keyFilter = opts.permissionLevel; 37 | } 38 | } 39 | 40 | var options = { 41 | uri: this.jiraClient.buildURL('/application-properties'), 42 | method: 'GET', 43 | followAllRedirects: true, 44 | qs: qs 45 | }; 46 | 47 | return this.jiraClient.makeRequest(options, callback); 48 | }; 49 | 50 | /** 51 | * Modify an application property via PUT. The "value" field present in the PUT will override thee existing value. 52 | * 53 | * @method getProperties 54 | * @memberOf ApplicationPropertiesClient# 55 | * @param {Object} opts The options for modifying the application property. 56 | * @param opts.id The id of the property to be modified 57 | * @param opts.property The new data for the property. See 58 | * {@link https://docs.atlassian.com/jira/REST/latest/#d2e4891} 59 | * @param [callback] Called when the property has been modified 60 | * @return {Promise} Resolved when the property has been modified 61 | */ 62 | this.setProperty = function (opts, callback) { 63 | var options = { 64 | uri: this.jiraClient.buildURL('/application-properties'), 65 | method: 'GET', 66 | followAllRedirects: true, 67 | body: opts.property 68 | }; 69 | 70 | return this.jiraClient.makeRequest(options, callback, 'Property Updated'); 71 | }; 72 | } -------------------------------------------------------------------------------- /api/auditing.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | 3 | var errorStrings = require('./../lib/error'); 4 | 5 | module.exports = AuditingClient; 6 | 7 | /** 8 | * Used to access Jira REST endpoints in '/rest/api/2/auditing' 9 | * @param {JiraClient} jiraClient 10 | * @constructor AuditingClient 11 | */ 12 | function AuditingClient(jiraClient) { 13 | this.jiraClient = jiraClient; 14 | 15 | /** 16 | * Returns auditing records filtered using provided parameters 17 | * 18 | * @method getAudits 19 | * @memberOf AuditingClient# 20 | * @param opts The filtering options for retrieving audits. 21 | * @param [opts.offset] The number of record from which search starts 22 | * @param [opts.limit] Maximum number of returned results (if is limit is <= 0 or > 1000, it will be set do default 23 | * value: 1000) 24 | * @param [opts.filter] Text query; each record that will be returned must contain the provided text in one of its 25 | * fields 26 | * @param [opts.from] Timestamp in past; 'from' must be less or equal 'to', otherwise the result set will be empty 27 | * only records that where created in the same moment or after the 'from' timestamp will be provided in 28 | * response 29 | * @param [opts.to] Timestamp in past; 'from' must be less or equal 'to', otherwise the result set will be empty 30 | * only records that where created in the same moment or earlier than the 'to' timestamp will be provided in 31 | * response 32 | * @param [callback] Called when the audits are retrieved. 33 | * @return {Promise} Resolved when the audits are retrieved. 34 | */ 35 | this.getAudits = function (opts, callback) { 36 | var options = { 37 | uri: this.jiraClient.buildURL('/auditing/record'), 38 | json: true, 39 | followAllRedirects: true, 40 | method: 'GET', 41 | qs: { 42 | offset: opts.offset, 43 | limit: opts.limit, 44 | filter: opts.filter, 45 | from: opts.from, 46 | to: opts.to 47 | } 48 | }; 49 | 50 | return this.jiraClient.makeRequest(options, callback); 51 | }; 52 | 53 | /** 54 | * 55 | * @method createAudit 56 | * @memberOf AuditingClient# 57 | * @param opts The request options. 58 | * @param opts.audit See {@link https://docs.atlassian.com/jira/REST/latest/#d2e2557} 59 | * @param [callback] Called when the audit is created. 60 | * @return {Promise} Resolved when the audit is created. 61 | */ 62 | this.createAudit = function (opts, callback) { 63 | if (!opts.audit) { 64 | throw new Error(errorStrings.NO_AUDIT_ERROR); 65 | } 66 | 67 | var options = { 68 | uri: this.jiraClient.buildURL('/auditing/record'), 69 | json: true, 70 | followAllRedirects: true, 71 | method: 'POST', 72 | body: opts.audit 73 | }; 74 | 75 | return this.jiraClient.makeRequest(options, callback, 'Audit Record Added'); 76 | }; 77 | } -------------------------------------------------------------------------------- /api/reindex.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | 3 | module.exports = ReindexClient; 4 | 5 | /** 6 | * Used to access Jira REST endpoints in '/rest/api/2/reindex' 7 | * 8 | * @param {JiraClient} jiraClient 9 | * @constructor ReindexClient 10 | */ 11 | function ReindexClient(jiraClient) { 12 | this.jiraClient = jiraClient; 13 | 14 | /** 15 | * Kicks off a reindex. Need Admin permissions to perform this reindex. 16 | * 17 | * @method doReindex 18 | * @memberOf ReindexClient# 19 | * @param opts The request options sent to the Jira API. 20 | * @param {string} [opts.type] Case insensitive String indicating type of reindex. If omitted, then defaults to 21 | * BACKGROUND_PREFERRED 22 | * @param {boolean} [opts.indexComments=false] Indicates that comments should also be reindexed. Not relevant for 23 | * foreground reindex, where comments are always reindexed. 24 | * @param {boolean} [opts.indexChangeHistory=false] Indicates that changeHistory should also be reindexed. Not 25 | * relevant for foreground reindex, where changeHistory is always reindexed. 26 | * @param [callback] Called when the reindex has been started. 27 | * @return {Promise} Resolved when the reindex has been started. 28 | */ 29 | this.doReindex = function (opts, callback) { 30 | var options = { 31 | uri: this.jiraClient.buildURL('/reindex'), 32 | method: 'POST', 33 | json: true, 34 | followAllRedirects: true, 35 | qs: { 36 | type: opts.type, 37 | indexComments: opts.indexComments, 38 | indexChangeHistory: opts.indexChangeHistory 39 | } 40 | }; 41 | 42 | return this.jiraClient.makeRequest(options, callback); 43 | }; 44 | 45 | /** 46 | * Gets information on the system reindexes. If a reindex is currently taking place then information about this 47 | * reindex is returned. If there is no active index task, then returns information about the latest reindex task 48 | * run, otherwise returns a 404 indicating that no reindex has taken place. 49 | * 50 | * @method getReindex 51 | * @memberOf ReindexClient# 52 | * @param opts The request options sent to the Jira API. 53 | * @param [opts.taskId] The id of an indexing task you wish to obtain details on. If omitted, then defaults to the 54 | * standard behaviour and returns information on the active reindex task, or the last task to run if no reindex 55 | * is taking place. . If there is no reindexing task with that id then a 404 is returned. 56 | * @param [callback] Called when the reindex data has been retrieved. 57 | * @return {Promise} Resolved when the reindex data has been retrieved. 58 | */ 59 | this.getReindex = function (opts, callback) { 60 | var options = { 61 | uri: this.jiraClient.buildURL('/reindex'), 62 | method: 'GET', 63 | json: true, 64 | followAllRedirects: true, 65 | qs: { 66 | taskId: opts.taskId 67 | } 68 | }; 69 | 70 | return this.jiraClient.makeRequest(options, callback); 71 | } 72 | } -------------------------------------------------------------------------------- /api/attachment.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | 3 | var errorStrings = require('./../lib/error'); 4 | 5 | module.exports = AttachmentClient; 6 | 7 | /** 8 | * Used to access Jira REST endpoints in '/rest/api/2/atachment' 9 | * 10 | * @constructor AttachmentClient 11 | * @param {JiraClient} jiraClient 12 | */ 13 | function AttachmentClient(jiraClient) { 14 | this.jiraClient = jiraClient; 15 | 16 | /** 17 | * Returns the meta-data for an attachment, including the URI of the actual attached file. 18 | * 19 | * @method getAttachment 20 | * @memberOf AttachmentClient# 21 | * @param {Object} opts The options for the API request. 22 | * @param {string} opts.attachmentId The id of the attachment to retrieve 23 | * @param {callback} [callback] Called when the attachment metadata is retrieved. 24 | * @return {Promise} Resolved when the attachment metadata is retrieved. 25 | */ 26 | this.getAttachment = function (opts, callback) { 27 | if (!opts.attachmentId) { 28 | throw new Error(errorStrings.NO_ATTACHMENT_ID_ERROR); 29 | } 30 | 31 | var options = { 32 | uri: this.jiraClient.buildURL('/attachment/' + opts.attachmentId), 33 | method: 'GET', 34 | json: true, 35 | followAllRedirects: true 36 | }; 37 | 38 | return this.jiraClient.makeRequest(options, callback); 39 | }; 40 | 41 | /** 42 | * Remove an attachment from an issue. 43 | * 44 | * @method deleteAttachment 45 | * @memberOf AttachmentClient# 46 | * @param {Object} opts The options for the API request. 47 | * @param {string} opts.attachmentId The id of the attachment to delete 48 | * @param {callback} [callback] Called when the attachment is deleted. 49 | * @return {Promise} Resolved when the attachment is deleted. 50 | */ 51 | this.deleteAttachment = function (opts, callback) { 52 | if (!opts.attachmentId) { 53 | throw new Error(errorStrings.NO_ATTACHMENT_ID_ERROR); 54 | } 55 | 56 | var options = { 57 | uri: this.jiraClient.buildURL('/attachment/' + opts.attachmentId), 58 | method: 'DELETE', 59 | json: true, 60 | followAllRedirects: true 61 | }; 62 | 63 | return this.jiraClient.makeRequest(options, callback, 'Attachment Deleted'); 64 | }; 65 | 66 | 67 | /** 68 | * Returns the meta informations for an attachments, specifically if they are enabled and the maximum upload size 69 | * allowed. 70 | * 71 | * @method getGlobalAttachmentMetadata 72 | * @memberOf AttachmentClient# 73 | * @param {Object} [opts] This API request actually takes no options; this parameter is ignored. 74 | * @param {callback} [callback] Called when the metadata is retrieved. 75 | * @return {Promise} Resolved when the metadata is retrieved. 76 | */ 77 | this.getGlobalAttachmentMetadata = function (opts, callback) { 78 | var options = { 79 | uri: this.jiraClient.buildURL('/attachment/meta'), 80 | method: 'GET', 81 | json: true, 82 | followAllRedirects: true 83 | }; 84 | 85 | return this.jiraClient.makeRequest(options, callback); 86 | }; 87 | } 88 | -------------------------------------------------------------------------------- /api/myPreferences.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | 3 | module.exports = MyPreferencesClient; 4 | 5 | /** 6 | * Used to access Jira REST endpoints in '/rest/api/2/mypreferences' 7 | * 8 | * @param {JiraClient} jiraClient 9 | * @constructor MyPreferencesClient 10 | */ 11 | function MyPreferencesClient(jiraClient) { 12 | this.jiraClient = jiraClient; 13 | 14 | /** 15 | * Gets preference of the currently logged in user. Preference key must be provided as input parameter (key). 16 | * The value is returned exactly as it is. 17 | * 18 | * @method getPreference 19 | * @memberOf MyPreferencesClient# 20 | * @param opts The request options send to the Jira API. 21 | * @param opts.key Key of the preference to be returned. 22 | * @param [callback] Called when the preference has been retrieved. 23 | * @return {Promise} Resolved when the preference has been retrieved. 24 | */ 25 | this.getPreference = function (opts, callback) { 26 | var options = { 27 | uri: this.jiraClient.buildURL('/mypreferences'), 28 | method: 'GET', 29 | json: true, 30 | followAllRedirects: true, 31 | qs: { 32 | key: opts.key 33 | } 34 | }; 35 | 36 | return this.jiraClient.makeRequest(options, callback); 37 | }; 38 | 39 | /** 40 | * Sets preference of the currently logged in user. Preference key must be provided as input parameters (key). 41 | * 42 | * @method editPreference 43 | * @memberOf MyPreferencesClient# 44 | * @param opts The request options send to the Jira API. 45 | * @param opts.key Key of the preference to be edited. 46 | * @param opts.value The new value to set for the preference. 47 | * @param [callback] Called when the preference has been edited. 48 | * @return {Promise} Resolved when the preference has been edited. 49 | */ 50 | this.editPreference = function (opts, callback) { 51 | var options = { 52 | uri: this.jiraClient.buildURL('/mypreferences'), 53 | method: 'PUT', 54 | json: true, 55 | followAllRedirects: true, 56 | qs: { 57 | key: opts.key 58 | }, 59 | body: opts.value 60 | }; 61 | 62 | return this.jiraClient.makeRequest(options, callback); 63 | }; 64 | 65 | /** 66 | * Removes preference of the currently logged in user. Preference key must be provided as input parameters (key). 67 | * 68 | * @method deletePreference 69 | * @memberOf MyPreferencesClient# 70 | * @param opts The request options send to the Jira API. 71 | * @param opts.key Key of the preference to be deleted. 72 | * @param [callback] Called when the preference has been deleted. 73 | * @return {Promise} Resolved when the preference has been deleted. 74 | */ 75 | this.deletePreference = function (opts, callback) { 76 | var options = { 77 | uri: this.jiraClient.buildURL('/mypreferences'), 78 | method: 'DELETE', 79 | json: true, 80 | followAllRedirects: true, 81 | qs: { 82 | key: opts.key 83 | } 84 | }; 85 | 86 | return this.jiraClient.makeRequest(options, callback); 87 | } 88 | } -------------------------------------------------------------------------------- /api/worklog.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | 3 | module.exports = WorklogClient; 4 | 5 | /** 6 | * Used to access Jira REST endpoints in '/rest/api/2/worklog' 7 | * 8 | * @param {JiraClient} jiraClient 9 | * @constructor WorkLogClient 10 | */ 11 | function WorklogClient(jiraClient) { 12 | this.jiraClient = jiraClient; 13 | 14 | /** 15 | * Returns worklogs id and delete time of worklogs that were deleted since given time. The returns set of worklogs is 16 | * limited to 1000 elements. This API will not return worklogs deleted during last minute. 17 | * 18 | * @method getWorklogDeleted 19 | * @memberOf WorklogClient# 20 | * @param {Object} opts The request options sent to the Jira API 21 | * @param {number} opts.since A date time in unix timestamp format since when deleted worklogs will be returned. 22 | * Default: 0 23 | * @param [callback] Called when the search results are retrieved. 24 | * @return {Promise} Resolved when the search results are retrieved. 25 | */ 26 | this.getWorklogDeleted = function (opts, callback) { 27 | var options = { 28 | uri: this.jiraClient.buildURL('/worklog/deleted'), 29 | method: 'GET', 30 | json: true, 31 | followAllRedirects: true, 32 | qs: { 33 | since: opts.since 34 | } 35 | }; 36 | return this.jiraClient.makeRequest(options, callback) 37 | }; 38 | 39 | /** 40 | * Returns Returns worklogs for given worklog ids. Only worklogs to which the calling user has permissions, 41 | * will be included in the result. The returns set of worklogs is limited to 1000 elements. 42 | * 43 | * @method worklogList 44 | * @memberOf WorklogClient# 45 | * @param {Object} opts The request options sent to the Jira API 46 | * @param {array} [opts.ids] a JSON array named ids which contains a list of issue IDs 47 | * @param [callback] Called when the search results are retrieved. 48 | * @return {Promise} Resolved when the search results are retrieved. 49 | */ 50 | this.worklogList = function (opts, callback) { 51 | var options = { 52 | uri: this.jiraClient.buildURL('/worklog/list'), 53 | method: 'POST', 54 | json: true, 55 | followAllRedirects: true, 56 | body: { 57 | ids: opts.ids 58 | } 59 | }; 60 | return this.jiraClient.makeRequest(options, callback) 61 | }; 62 | 63 | /** 64 | * Returns worklogs id and update time of worklogs that were updated since given time. The returns set of worklogs is 65 | * limited to 1000 elements. This API will not return worklogs deleted during last minute. 66 | * 67 | * @method getWorklogUpdated 68 | * @memberOf WorklogClient# 69 | * @param {Object} opts The request options sent to the Jira API 70 | * @param {number} opts.since A date time in unix timestamp format since when updated worklogs will be returned. 71 | * Default: 0 72 | * @param [callback] Called when the search results are retrieved. 73 | * @return {Promise} Resolved when the search results are retrieved. 74 | */ 75 | this.getWorklogUpdated = function (opts, callback) { 76 | var options = { 77 | uri: this.jiraClient.buildURL('/worklog/updated'), 78 | method: 'GET', 79 | json: true, 80 | followAllRedirects: true, 81 | qs: { 82 | since: opts.since 83 | } 84 | }; 85 | return this.jiraClient.makeRequest(options, callback) 86 | } 87 | } 88 | -------------------------------------------------------------------------------- /api/developmentInformation.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | 3 | module.exports = DevelopmentInformationClient; 4 | 5 | /** 6 | * Used to access Jira REST endpoints in ' /rest/devinfo/0.10' 7 | * @param {JiraClient} jiraClient 8 | * @constructor DevelopmentInformationClient 9 | */ 10 | function DevelopmentInformationClient(jiraClient) { 11 | this.jiraClient = jiraClient; 12 | 13 | this.store = function (params, callback) { 14 | const options = { 15 | uri: this.jiraClient.buildAbstractURL("/devinfo/0.10/bulk"), 16 | method: 'POST', 17 | headers: { 18 | Authorization: params.Authorization 19 | }, 20 | json: true, 21 | followAllRedirects: true, 22 | body: { 23 | repositories: params.repositories, 24 | preventTransitions: params.preventTransitions, 25 | properties: params.properties, 26 | providerMetadata: params.providerMetadata, 27 | } 28 | }; 29 | 30 | return this.jiraClient.makeRequest(options, callback); 31 | } 32 | 33 | this.getRepository = function (params, callback) { 34 | const options = { 35 | uri: this.jiraClient.buildAbstractURL("/devinfo/0.10/repository/" + params.repositoryId), 36 | method: 'GET', 37 | headers: { 38 | Authorization: params.Authorization 39 | }, 40 | json: true, 41 | followAllRedirects: true 42 | }; 43 | 44 | return this.jiraClient.makeRequest(options, callback); 45 | } 46 | 47 | this.deleteRepository = function (params, callback) { 48 | const options = { 49 | uri: this.jiraClient.buildAbstractURL("/devinfo/0.10/repository/" + params.repositoryId), 50 | method: 'DELETE', 51 | headers: { 52 | Authorization: params.Authorization 53 | }, 54 | json: true, 55 | followAllRedirects: true, 56 | qs: { 57 | _updateSequenceId: params._updateSequenceId 58 | } 59 | }; 60 | 61 | return this.jiraClient.makeRequest(options, callback); 62 | } 63 | 64 | this.deleteByProperties = function (params, callback) { 65 | const options = { 66 | uri: this.jiraClient.buildAbstractURL("/devinfo/0.10/bulkByProperties"), 67 | method: 'DELETE', 68 | headers: { 69 | Authorization: params.Authorization 70 | }, 71 | json: true, 72 | followAllRedirects: true, 73 | qs: { 74 | _updateSequenceId: params._updateSequenceId 75 | } 76 | }; 77 | 78 | return this.jiraClient.makeRequest(options, callback); 79 | } 80 | 81 | this.checkExists = function (params, callback) { 82 | const options = { 83 | uri: this.jiraClient.buildAbstractURL("/devinfo/0.10/existsByProperties"), 84 | method: 'GET', 85 | headers: { 86 | Authorization: params.Authorization 87 | }, 88 | json: true, 89 | followAllRedirects: true, 90 | qs: { 91 | _updateSequenceId: params._updateSequenceId 92 | } 93 | }; 94 | 95 | return this.jiraClient.makeRequest(options, callback); 96 | } 97 | 98 | this.deleteEntity = function (params, callback) { 99 | const options = { 100 | uri: this.jiraClient.buildAbstractURL( 101 | "/devinfo/0.10/repository/" + 102 | params.repositoryId + "/" + 103 | params.entityType + "/" + 104 | params.entityId 105 | ), 106 | method: 'DELETE', 107 | headers: { 108 | Authorization: params.Authorization 109 | }, 110 | json: true, 111 | followAllRedirects: true, 112 | qs: { 113 | _updateSequenceId: params._updateSequenceId 114 | } 115 | }; 116 | 117 | return this.jiraClient.makeRequest(options, callback); 118 | } 119 | } 120 | -------------------------------------------------------------------------------- /api/issueLink.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | 3 | var errorStrings = require('./../lib/error'); 4 | 5 | module.exports = IssueLinkClient; 6 | 7 | /** 8 | * Used to access Jira REST endpoints in '/rest/api/2/issueLink' 9 | * @param {JiraClient} jiraClient 10 | * @constructor IssueLinkClient 11 | */ 12 | function IssueLinkClient(jiraClient) { 13 | this.jiraClient = jiraClient; 14 | 15 | /** 16 | * Creates an issue link between two issues. The user requires the link issue permission for the issue which will 17 | * be linked to another issue. The specified link type in the request is used to create the link and will create a 18 | * link from the first issue to the second issue using the outward description. It also create a link from the 19 | * second issue to the first issue using the inward description of the issue link type. It will add the supplied 20 | * comment to the first issue. The comment can have a restriction who can view it. If group is specified, only 21 | * users of this group can view this comment, if roleLevel is specified only users who have the specified role can 22 | * view this comment. The user who creates the issue link needs to belong to the specified group or have the 23 | * specified role. 24 | * 25 | * @memberOf IssueLinkClient# 26 | * @method createIssueLink 27 | * @param opts The options for the request sent to the Jira API 28 | * @param opts.issueLink See {@link https://docs.atlassian.com/jira/REST/latest/#d2e5010} 29 | * @param [callback] Called when the link has been created. 30 | * @return {Promise} Resolved when the link has been created. 31 | */ 32 | this.createIssueLink = function (opts, callback) { 33 | if (!opts.issueLink) { 34 | throw new Error(errorStrings.NO_ISSUE_LINK_ERROR); 35 | } 36 | 37 | var options = { 38 | method: 'POST', 39 | uri: this.jiraClient.buildURL('/issueLink'), 40 | json: true, 41 | followAllRedirects: true, 42 | body: opts.issueLink 43 | }; 44 | 45 | return this.jiraClient.makeRequest(options, callback, 'Issue Link Created'); 46 | }; 47 | 48 | /** 49 | * Gets an issue link with the specified id. 50 | * 51 | * @method getIssueLink 52 | * @memberOf IssueLinkClient# 53 | * @param opts The options used in the request to the Jira API 54 | * @param opts.linkId The id of the link to retrieve. 55 | * @param [callback] Called when the Issue Link has been retrieved. 56 | * @return {Promise} Resolved when the Issue Link has been retrieved. 57 | */ 58 | this.getIssueLink = function (opts, callback) { 59 | if (!opts.linkId) { 60 | throw new Error(errorStrings.NO_ISSUE_LINK_ID_ERROR); 61 | } 62 | 63 | var options = { 64 | method: 'GET', 65 | uri: this.jiraClient.buildURL('/issueLink/' + opts.linkId), 66 | json: true, 67 | followAllRedirects: true 68 | }; 69 | 70 | return this.jiraClient.makeRequest(options, callback); 71 | }; 72 | 73 | /** 74 | * Deletes an issue link with the specified id. To be able to delete an issue link you must be able to view both 75 | * issues and must have the link issue permission for at least one of the issues. 76 | * 77 | * @method deleteIssueLink 78 | * @memberOf IssueLinkClient# 79 | * @param opts The options used in the request to the Jira API 80 | * @param opts.linkId The id of the link to delete. 81 | * @param [callback] Called when the Issue Link has been deleted. 82 | * @return {Promise} Resolved when the Issue Link has been deleted. 83 | */ 84 | this.deleteIssueLink = function (opts, callback) { 85 | if (!opts.linkId) { 86 | throw new Error(errorStrings.NO_ISSUE_LINK_ID_ERROR); 87 | } 88 | 89 | var options = { 90 | method: 'DELETE', 91 | uri: this.jiraClient.buildURL('/issueLink/' + opts.linkId), 92 | json: true, 93 | followAllRedirects: true 94 | }; 95 | 96 | return this.jiraClient.makeRequest(options, callback, 'Issue Link Deleted'); 97 | }; 98 | } -------------------------------------------------------------------------------- /api/webhook.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | 3 | module.exports = WebhookClient; 4 | 5 | /** 6 | * Used to access Jira REST endpoints in '/rest/webhook/1.0/webhook' 7 | * 8 | * @param {JiraClient} jiraClient 9 | * @constructor WebhookClient 10 | */ 11 | function WebhookClient(jiraClient) { 12 | this.jiraClient = jiraClient; 13 | 14 | /** 15 | * Returns a list of all registered webhooks. 16 | * 17 | * @method getAllWebhooks 18 | * @memberOf WebhookClient# 19 | * @param opts Ignored 20 | * @param [callback] Called when the webhooks have been retrieved. 21 | * @return {Promise} Resolved when the webhooks have been retrieved. 22 | */ 23 | this.getAllWebhooks = function (opts, callback) { 24 | var options = { 25 | uri: this.jiraClient.buildWebhookURL('/webhook'), 26 | method: 'GET', 27 | json: true, 28 | followAllRedirects: true 29 | }; 30 | 31 | return this.jiraClient.makeRequest(options, callback); 32 | }; 33 | 34 | /** 35 | * Returns a webhook with a specific ID. 36 | * 37 | * @method getWebhook 38 | * @memberOf WebhookClient# 39 | * @param opts The options sent to the JIRA API. 40 | * @param opts.webhookURI The URI of the webhook to delete. 41 | * @param opts.webhookId The numerical webhook ID. This is only used if webhookURI is falsey. 42 | * @param [callback] Called when the webhook has been retrieved. 43 | * @return {Promise} Resolved when the webhook has been retrieved. 44 | */ 45 | this.getWebhook = function (opts, callback) { 46 | var options = { 47 | uri: opts.webhookURI || this.jiraClient.buildWebhookURL('/webhook/' + opts.webhookId), 48 | method: 'GET', 49 | json: true, 50 | followAllRedirects: true 51 | }; 52 | 53 | return this.jiraClient.makeRequest(options, callback); 54 | }; 55 | 56 | /** 57 | * Registers a new webhook. 58 | * 59 | * @method createWebhook 60 | * @memberOf WebhookClient# 61 | * @param opts The options sent to the JIRA API. 62 | * @param opts.name The name of the webhook. 63 | * @param opts.url The URL of the webhook. 64 | * @param opts.events An array of events with which the webhook should be registered. See 65 | * {@link https://developer.atlassian.com/jiradev/jira-apis/webhooks#Webhooks-configureConfiguringawebhook}. 66 | * @param opts.enabled Whether the webhook is enabled. 67 | * @param opts.filter An object containing filter configuration. 68 | * @param opts.filter.issue-related-events-section A filter for issues, written in JQL. 69 | * @param opts.excludeBody Whether to send an empty body to the webhook URL. 70 | * @param [callback] Called when the webhook has been retrieved. 71 | * @return {Promise} Resolved when the webhook has been retrieved. 72 | */ 73 | this.createWebhook = function (opts, callback) { 74 | var options = { 75 | uri: this.jiraClient.buildWebhookURL('/webhook'), 76 | method: 'POST', 77 | json: true, 78 | body: opts, 79 | followAllRedirects: true 80 | }; 81 | 82 | return this.jiraClient.makeRequest(options, callback); 83 | }; 84 | 85 | /** 86 | * Deletes a registered webhook. 87 | * 88 | * @method deleteWebhook 89 | * @memberOf WebhookClient# 90 | * @param opts The options sent to the JIRA API. 91 | * @param opts.webhookURI The URI of the webhook to delete. 92 | * @param opts.webhookId The numerical webhook ID. This is only used if webhookURI is falsey. 93 | * @param [callback] Called when the webhook has been deleted. 94 | * @return {Promise} Resolved when the webhook has been deleted. 95 | */ 96 | this.deleteWebhook = function (opts, callback) { 97 | var options = { 98 | uri: opts.webhookURI || this.jiraClient.buildWebhookURL('/webhook/' + opts.webhookId), 99 | method: 'DELETE', 100 | json: true, 101 | followAllRedirects: true 102 | }; 103 | 104 | return this.jiraClient.makeRequest(options, callback); 105 | }; 106 | } 107 | -------------------------------------------------------------------------------- /api/search.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | 3 | module.exports = SearchClient; 4 | 5 | /** 6 | * Used to access Jira REST endpoints in '/rest/api/2/search' 7 | * 8 | * @param {JiraClient} jiraClient 9 | * @constructor SearchClient 10 | */ 11 | function SearchClient(jiraClient) { 12 | this.jiraClient = jiraClient; 13 | 14 | /** 15 | * Searches for issues using JQL. 16 | * 17 | * Sorting the jql parameter is a full JQL expression, and includes an ORDER BY clause. 18 | * 19 | * The fields param (which can be specified multiple times) gives a comma-separated list of fields to include in 20 | * the response. This can be used to retrieve a subset of fields. A particular field can be excluded by prefixing 21 | * it with a minus. 22 | * 23 | * By default, only navigable (*navigable) fields are returned in this search resource. Note: the default is 24 | * different in the get-issue resource -- the default there all fields (*all). 25 | * 26 | * * *all - include all fields 27 | * * navigable - include just navigable fields 28 | * * summary,comment - include just the summary and comments 29 | * * -description - include navigable fields except the description (the default is *navigable for search) 30 | * * *all,-comment - include everything except comments 31 | * 32 | * Expanding Issues in the Search Result: It is possible to expand the issues returned by directly specifying the 33 | * expansion on the expand parameter passed in to this resources. 34 | * 35 | * For instance, to expand the "changelog" for all the issues on the search result, it is neccesary to specify 36 | * "changelog" as one of the values to expand. 37 | * 38 | * @method search 39 | * @memberOf SearchClient# 40 | * @param opts The options for the search. 41 | * @param {GET | POST} [opts.method=POST] search request method 42 | * @param {string} [opts.jql] The JQL query string 43 | * @param {number} [opts.startAt=0] The index of the first issue to return (0-based) 44 | * @param {number} [opts.maxResults=50] The maximum number of issues to return (defaults to 50). The maximum allowable 45 | * value is dictated by the JIRA property 'jira.search.views.default.max'. If you specify a value that is 46 | * higher than this number, your search results will be truncated. 47 | * @param {string} [opts.validateQuery=strict] Whether to validate the JQL query 48 | * @param {Array} [opts.fields] The list of fields to return for each issue. By default, all navigable fields are 49 | * returned. 50 | * @param {Array} [opts.expand] A list of the parameters to expand. 51 | * @param {Array} [opts.properties] A list of the properties to include (5 max). 52 | * @param {boolean} [opts.fieldsByKeys=false] Reference fields by their key (rather than ID). 53 | * @param {callback} [callback] Called with the search results. 54 | * @return {Promise} Resolved with the search results. 55 | */ 56 | this.search = function (opts, callback) { 57 | opts = opts || {}; 58 | opts.method = (opts.method || 'POST').toUpperCase(); 59 | 60 | var options = { 61 | uri: this.jiraClient.buildURL('/search'), 62 | method: opts.method, 63 | json: true, 64 | headers: { 65 | 'Content-Type': 'application/json' 66 | }, 67 | followAllRedirects: true, 68 | timeout: opts.timeout || 10000, 69 | }; 70 | 71 | var fields = opts.method === 'POST' ? opts.fields : opts.fields && opts.fields.join(','); 72 | var expand = opts.method === 'POST' ? opts.expand : opts.expand && opts.expand.join(','); 73 | var properties = opts.method === 'POST' ? opts.properties : opts.properties && options.properties.join(','); 74 | 75 | var search_options = { 76 | jql: opts.jql, 77 | startAt: opts.startAt || 0, 78 | maxResults: opts.maxResults || 50, 79 | validateQuery: opts.validateQuery, 80 | fields, 81 | expand, 82 | properties, 83 | fieldsByKeys: opts.fieldsByKeys 84 | }; 85 | 86 | if (opts.method === 'POST') { 87 | options.body = search_options; 88 | } else { 89 | options.qs = search_options; 90 | } 91 | 92 | return this.jiraClient.makeRequest(options, callback); 93 | } 94 | } 95 | -------------------------------------------------------------------------------- /api/avatar.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | 3 | var fs = require('fs'); 4 | var path = require('path'); 5 | var errorStrings = require('./../lib/error'); 6 | 7 | module.exports = AvatarClient; 8 | 9 | /** 10 | * Used to access Jira REST endpoints in '/rest/api/2/avatar' 11 | * @param {JiraClient} jiraClient 12 | * @constructor AvatarClient 13 | */ 14 | function AvatarClient(jiraClient) { 15 | this.jiraClient = jiraClient; 16 | 17 | /** 18 | * Returns all system avatars of the given type. 19 | * 20 | * @method getAvatars 21 | * @memberOf AvatarClient# 22 | * @param opts The options to be used in the API request. 23 | * @param opts.avatarType The avatar type. May be 'project' or 'user'. 24 | * @param [callback] Called when the avatars are retrieved. 25 | * @return {Promise} Resolved when the avatars are retrieved. 26 | */ 27 | this.getAvatars = function (opts, callback) { 28 | if (!opts.avatarType) { 29 | throw new Error(errorStrings.NO_AVATAR_TYPE_ERROR); 30 | } 31 | var options = { 32 | method: 'GET', 33 | json: true, 34 | followAllRedirects: true, 35 | uri: this.jiraClient.buildURL('/avatar/' + opts.avatarType + '/system') 36 | }; 37 | 38 | return this.jiraClient.makeRequest(options, callback); 39 | }; 40 | 41 | /** 42 | * Creates a temporary avatar. This function doesn't seem to work the way the Jira API describes, so for now 43 | * just don't use it. 44 | * 45 | * @method createTemporaryAvatar 46 | * @memberOf AvatarClient# 47 | * @param opts The options to be used in the API request. 48 | * @param opts.avatarType The avatar type. May be 'project' or 'user'. 49 | * @param opts.avatarFilename The name of the file being uploaded 50 | * @param opts.avatarFileSize The size of the file 51 | * @param opts.avatarFilePath The path to the avatar file. 52 | * @param [callback] Called when the avatar is created. 53 | * @return {Promise} Resolved when the avatar is created. 54 | */ 55 | this.createTemporaryAvatar = function (opts, callback) { 56 | if (!opts.avatarType) { 57 | throw new Error(errorStrings.NO_AVATAR_TYPE_ERROR); 58 | } 59 | var size = fs.statSync(opts.avatarFilePath).size; 60 | var name = path.basename(opts.avatarFilePath); 61 | var options = { 62 | method: 'POST', 63 | json: true, 64 | followAllRedirects: true, 65 | uri: this.jiraClient.buildURL('/avatar/' + opts.avatarType + '/temporary'), 66 | headers: { 67 | "X-Atlassian-Token": "no-check" 68 | }, 69 | qs: { 70 | filename: name, 71 | size: size 72 | }, 73 | formData: { 74 | file: fs.createReadStream(opts.avatarFilePath) 75 | } 76 | }; 77 | delete options.body; 78 | 79 | return this.jiraClient.makeRequest(options, callback); 80 | }; 81 | 82 | /** 83 | * Updates the cropping instructions of the temporary avatar. This function doesn't seem to work the way the Jira 84 | * API describes, so for now just don't use it. 85 | * 86 | * @method cropTemporaryAvatar 87 | * @memberOf AvatarClient# 88 | * @param {Object} opts The options to be used in the API request. 89 | * @param {string} opts.avatarType The avatar type. May be 'project' or 'user'. 90 | * @param {Object} opts.crop See {@link https://docs.atlassian.com/jira/REST/latest/#d2e3316} 91 | * @param [callback] Called when the avatar has been cropped. 92 | * @return {Promise} Resolved when the avatar has been cropped. 93 | */ 94 | this.cropTemporaryAvatar = function (opts, callback) { 95 | if (!opts.avatarType) { 96 | throw new Error(errorStrings.NO_AVATAR_TYPE_ERROR); 97 | } 98 | 99 | var options = { 100 | method: 'POST', 101 | json: true, 102 | followAllRedirects: true, 103 | uri: this.jiraClient.buildURL('/avatar/' + opts.avatarType + '/temporaryCrop'), 104 | headers: { 105 | "X-Atlassian-Token": "no-check" 106 | }, 107 | body: opts.crop 108 | }; 109 | 110 | return this.jiraClient.makeRequest(options, callback); 111 | }; 112 | } -------------------------------------------------------------------------------- /api/component.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | 3 | module.exports = ComponentClient; 4 | 5 | /** 6 | * Used to access Jira REST endpoints in '/rest/api/2/component' 7 | * 8 | * @param {JiraClient} jiraClient 9 | * @constructor ComponentClient 10 | */ 11 | function ComponentClient(jiraClient) { 12 | this.jiraClient = jiraClient; 13 | 14 | /** 15 | * Create a component via POST. 16 | * 17 | * @method createComponent 18 | * @memberOf ComponentClient# 19 | * @param opts The request options sent to the Jira API 20 | * @param opts.component See {@link https://docs.atlassian.com/jira/REST/latest/#d2e3871} 21 | * @param [callback] Called when the component has been created. 22 | * @return {Promise} Resolved when the component has been created. 23 | */ 24 | this.createComponent = function (opts, callback) { 25 | var options = { 26 | uri: this.jiraClient.buildURL('/component'), 27 | method: 'POST', 28 | json: true, 29 | followAllRedirects: true, 30 | body: opts.component 31 | }; 32 | 33 | return this.jiraClient.makeRequest(options, callback); 34 | }; 35 | 36 | /** 37 | * Modify a component via PUT. Any fields present in the PUT will override existing values. As a convenience, if a 38 | * field is not present, it is silently ignored. If leadUserName is an empty string ("") the component lead will be 39 | * removed. 40 | * 41 | * @method editComponent 42 | * @memberOf ComponentClient# 43 | * @param opts The request options sent to the Jira API. 44 | * @param opts.id The id of the component to edit. 45 | * @param opts.component The new data to place in the component. See 46 | * {@link https://docs.atlassian.com/jira/REST/latest/#d2e3939} 47 | * @param [callback] Called when the component has beed edited. 48 | * @return {Promise} Resolved when the component has beed edited. 49 | */ 50 | this.editComponent = function (opts, callback) { 51 | var options = { 52 | uri: this.jiraClient.buildURL('/component/' + opts.id), 53 | method: 'PUT', 54 | json: true, 55 | followAllRedirects: true, 56 | body: opts.component 57 | }; 58 | 59 | return this.jiraClient.makeRequest(options, callback); 60 | }; 61 | 62 | /** 63 | * Get a project component. 64 | * 65 | * @method getComponent 66 | * @memberOf ComponentClient# 67 | * @param opts The options sent to the Jira API 68 | * @param opts.id The id of the component to edit. 69 | * @param [callback] Called when the component has been retrieved. 70 | * @return {Promise} Resolved when the component has been retrieved. 71 | */ 72 | this.getComponent = function (opts, callback) { 73 | var options = { 74 | uri: this.jiraClient.buildURL('/component/' + opts.id), 75 | method: 'GET', 76 | json: true, 77 | followAllRedirects: true 78 | }; 79 | 80 | return this.jiraClient.makeRequest(options, callback); 81 | }; 82 | 83 | /** 84 | * Delete a project component. 85 | * 86 | * @method deleteComponent 87 | * @memberOf ComponentClient# 88 | * @param opts The options sent to the Jira API 89 | * @param opts.id The id of the component to edit. 90 | * @param [opts.moveIssuesTo] The new component applied to issues whose 'id' component will be deleted. If this 91 | * value is null, then the 'id' component is simply removed from the related isues. 92 | * @param [callback] Called when the component has been deleted. 93 | * @return {Promise} Resolved when the component has been deleted. 94 | */ 95 | this.deleteComponent = function (opts, callback) { 96 | var options = { 97 | uri: this.jiraClient.buildURL('/component/' + opts.id), 98 | method: 'DELETE', 99 | json: true, 100 | followAllRedirects: true 101 | }; 102 | 103 | return this.jiraClient.makeRequest(options, callback, 'Project Component Deleted'); 104 | }; 105 | 106 | /** 107 | * Get counts of issues related to this component. 108 | * 109 | * @method getRelatedIssueCounts 110 | * @memberOf ComponentClient# 111 | * @param opts The options sent to the Jira API 112 | * @param opts.id The id of the component to edit. 113 | * @param [callback] Called when the count has been retrieved. 114 | * @return {Promise} Resolved when the count has been retrieved. 115 | */ 116 | this.getRelatedIssueCounts = function (opts, callback) { 117 | var options = { 118 | uri: this.jiraClient.buildURL('/component/' + opts.id + '/relatedIssueCounts'), 119 | method: 'GET', 120 | json: true, 121 | followAllRedirects: true 122 | }; 123 | 124 | return this.jiraClient.makeRequest(options, callback); 125 | } 126 | } -------------------------------------------------------------------------------- /types/api/board.d.ts: -------------------------------------------------------------------------------- 1 | import { Callback } from "../callback"; 2 | import { Board as BoardModel } from "../models"; 3 | 4 | export class Board { 5 | getAllBoards( 6 | opts?: { 7 | startAt?: number; 8 | maxResults?: number; 9 | type?: string; 10 | name?: string; 11 | projectKeyOrId?: string | number; 12 | accountIdLocation?: string; 13 | userkeyLocation?: string; 14 | usernameLocation?: string; 15 | projectLocation?: string; 16 | includePrivate?: boolean; 17 | negateLocationFiltering?: boolean; 18 | orderBy?: string; 19 | expand?: string; 20 | }, 21 | callback?: Callback 22 | ): Promise; 23 | createBoard( 24 | name: string, 25 | type: string, 26 | filterId: number, 27 | location: { 28 | type: string; 29 | projectKeyOrId: string; 30 | }, 31 | callback?: Callback 32 | ): Promise; 33 | getBoardByFilterId(opts: { 34 | filterId: number; 35 | startAt?: number; 36 | maxResults?: number; 37 | }, callback?: Callback): Promise; 38 | getBoard(opts: { 39 | boardId: number | string; 40 | }, callback?: Callback): Promise; 41 | deleteBoard(opts: { 42 | boardId: number | string; 43 | }, callback?: Callback): Promise; 44 | getIssuesForBacklog(opts: { 45 | boardId: number | string; 46 | startAt?: number; 47 | maxResults?: number; 48 | jql?: string; 49 | validateQuery?: boolean; 50 | fields?: string[]; 51 | expand?: string; 52 | }, callback?: Callback): Promise; 53 | getConfiguration(opts: { 54 | boardId: number | string; 55 | }, callback?: Callback): Promise; 56 | getEpics(opts: { 57 | boardId: number | string; 58 | startAt?: number; 59 | maxResults?: number; 60 | done?: string; 61 | }, callback?: Callback): Promise; 62 | getIssuesWithoutEpic(opts: { 63 | boardId: number | string; 64 | startAt?: number; 65 | maxResults?: number; 66 | jql?: string; 67 | validateQuery?: boolean; 68 | fields?: string[]; 69 | expand?: string; 70 | }, callback?: Callback): Promise; 71 | getIssuesForEpic(opts: { 72 | boardId: number | string; 73 | epicId: number | string; 74 | startAt?: number; 75 | maxResults?: number; 76 | jql?: string; 77 | validateQuery?: boolean; 78 | fields?: string[]; 79 | expand?: string; 80 | }, callback?: Callback): Promise; 81 | getFeaturesForBoard(opts: { 82 | boardId: number | string; 83 | }, callback?: Callback): Promise; 84 | toggleFeatures(opts: { 85 | boardId: number | string; 86 | boardIdBody?: number | string; 87 | feature?: string; 88 | enabling?: boolean; 89 | }, callback?: Callback): Promise; 90 | getIssuesForBoard(opts: { 91 | boardId: number | string; 92 | startAt?: number; 93 | maxResults?: number; 94 | jql?: string; 95 | validateQuery?: boolean; 96 | fields?: string[]; 97 | expand?: string; 98 | }, callback?: Callback): Promise; 99 | moveIssuesToBoard(opts: { 100 | boardId: number | string; 101 | issues?: string[]; 102 | rankBeforeIssue?: string; 103 | rankAfterIssue?: string; 104 | rankCustomFieldId?: number | string; 105 | }, callback?: Callback): Promise; 106 | getProjects(opts: { 107 | boardId: number | string; 108 | startAt?: number; 109 | maxResults?: number; 110 | }, callback?: Callback): Promise; 111 | getProjectsFull(opts: { 112 | boardId: number | string; 113 | }, callback?: Callback): Promise; 114 | getBoardPropertyKeys(opts: { 115 | boardId: number | string; 116 | }, callback?: Callback): Promise; 117 | getBoardProperty(opts: { 118 | boardId: number | string; 119 | propertyKey: string; 120 | }, callback?: Callback): Promise; 121 | setBoardProperty(opts: { 122 | boardId: number | string; 123 | propertyKey: string; 124 | property: any; 125 | }, callback?: Callback): Promise; 126 | deleteBoardProperty(opts: { 127 | boardId: number | string; 128 | propertyKey: string; 129 | }, callback?: Callback): Promise; 130 | getAllQuickFilters(opts: { 131 | boardId: number | string; 132 | startAt?: number; 133 | maxResults?: number; 134 | }, callback?: Callback): Promise; 135 | getQuickFilter(opts: { 136 | boardId: number | string; 137 | quickFilterId: number | string; 138 | }, callback?: Callback): Promise; 139 | getReportsForBoard(opts: { 140 | boardId: number | string; 141 | }, callback?: Callback): Promise; 142 | getAllSprints(opts: { 143 | boardId: number | string; 144 | startAt?: number; 145 | maxResults?: number; 146 | state?: string; 147 | }, callback?: Callback): Promise; 148 | getIssuesForSprint(opts: { 149 | boardId: number | string; 150 | sprintId: number | string; 151 | startAt?: number; 152 | maxResults?: number; 153 | jql?: string; 154 | validateQuery?: boolean; 155 | fields?: string[]; 156 | expand?: string; 157 | }, callback?: Callback): Promise; 158 | getAllVersions(opts: { 159 | boardId: number | string; 160 | startAt?: number; 161 | maxResults?: number; 162 | released?: string; 163 | }, callback?: Callback): Promise; 164 | } 165 | -------------------------------------------------------------------------------- /api/issueLinkType.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | 3 | var errorStrings = require('./../lib/error'); 4 | 5 | module.exports = IssueLinkTypeClient; 6 | 7 | /** 8 | * Used to access Jira REST endpoints in '/rest/api/2/issueLinkType' 9 | * @param {JiraClient} jiraClient 10 | * @constructor IssueLinkTypeClient 11 | */ 12 | function IssueLinkTypeClient(jiraClient) { 13 | this.jiraClient = jiraClient; 14 | 15 | /** 16 | * Get a list of available issue link types, if issue linking is enabled. Each issue link type has an id, a name 17 | * and a label for the outward and inward link relationship. 18 | * 19 | * @method getAvailableTypes 20 | * @memberOf IssueLinkTypeClient# 21 | * @param opts The request options for the API. Ignored in this function. 22 | * @param [callback] Called when the available IssueLink types are retrieved. 23 | * @return {Promise} Resolved when the available IssueLink types are retrieved. 24 | */ 25 | this.getAvailableTypes = function (opts, callback) { 26 | var options = { 27 | uri: this.jiraClient.buildURL('/issueLinkType'), 28 | method: 'GET', 29 | json: true, 30 | followAllRedirects: true 31 | }; 32 | 33 | return this.jiraClient.makeRequest(options, callback); 34 | }; 35 | 36 | /** 37 | * Create a new issue link type. 38 | * 39 | * @method createIssueLinkType 40 | * @memberOf IssueLinkTypeClient# 41 | * @param opts The request options sent to the Jira API 42 | * @param opts.linkType See {@link https://docs.atlassian.com/jira/REST/latest/#d2e2018} 43 | * @param [callback] Called when the IssueLink type has been created. 44 | * @return {Promise} Resolved when the IssueLink type has been created. 45 | */ 46 | this.createIssueLinkType = function (opts, callback) { 47 | var options = { 48 | uri: this.jiraClient.buildURL('/issueLinkType'), 49 | method: 'POST', 50 | json: true, 51 | followAllRedirects: true, 52 | body: opts.linkType 53 | }; 54 | 55 | return this.jiraClient.makeRequest(options, callback); 56 | }; 57 | 58 | /** 59 | * Gets for a given issue link type id all information about this issue link type. 60 | * 61 | * @method getIssueLinkType 62 | * @memberOf IssueLinkTypeClient# 63 | * @param opts The request options sent to the Jira API 64 | * @param opts.issueLinkTypeId The id of the IssueLink type to retrieve. 65 | * @param [callback] Called when the IssueLink type has been retrieved 66 | * @return {Promise} Resolved when the IssueLink type has been retrieved 67 | */ 68 | this.getIssueLinkType = function (opts, callback) { 69 | if (!opts.issueLinkTypeId) { 70 | throw new Error(errorStrings.NO_ISSUE_LINK_TYPE_ID); 71 | } 72 | 73 | var options = { 74 | uri: this.jiraClient.buildURL('/issueLinkType/' + opts.issueLinkTypeId), 75 | method: 'GET', 76 | json: true, 77 | followAllRedirects: true 78 | }; 79 | 80 | return this.jiraClient.makeRequest(options, callback); 81 | }; 82 | 83 | /** 84 | * Delete the specified issue link type. 85 | * 86 | * @method deleteIssueLinkType 87 | * @memberOf IssueLinkTypeClient# 88 | * @param opts The request options sent to the Jira API 89 | * @param opts.issueLinkTypeId The id of the IssueLink type to delete. 90 | * @param [callback] Called when the IssueLink type has been delete 91 | * @return {Promise} Resolved when the IssueLink type has been delete 92 | */ 93 | this.deleteIssueLinkType = function (opts, callback) { 94 | if (!opts.issueLinkTypeId) { 95 | throw new Error(errorStrings.NO_ISSUE_LINK_TYPE_ID); 96 | } 97 | 98 | var options = { 99 | uri: this.jiraClient.buildURL('/issueLinkType/' + opts.issueLinkTypeId), 100 | method: 'DELETE', 101 | json: true, 102 | followAllRedirects: true 103 | }; 104 | 105 | return this.jiraClient.makeRequest(options, callback, 'IssueLink type deleted.'); 106 | }; 107 | 108 | /** 109 | * Update the specified issue link type. 110 | * 111 | * @method editIssueLinkType 112 | * @memberOf IssueLinkTypeClient# 113 | * @param opts The request options sent to the Jira API 114 | * @param opts.issueLinkTypeId The id of the IssueLink type to retrieve. 115 | * @param opts.linkType See {@link https://docs.atlassian.com/jira/REST/latest/#d2e2071} 116 | * @param [callback] Called when the IssueLink type has been updated. 117 | * @return {Promise} Resolved when the IssueLink type has been updated. 118 | */ 119 | this.editIssueLinkType = function (opts, callback) { 120 | if (!opts.issueLinkTypeId) { 121 | throw new Error(errorStrings.NO_ISSUE_LINK_TYPE_ID); 122 | } 123 | 124 | var options = { 125 | uri: this.jiraClient.buildURL('/issueLinkType/' + opts.issueLinkTypeId), 126 | method: 'PUT', 127 | json: true, 128 | followAllRedirects: true, 129 | body: opts.issueLinkType 130 | }; 131 | 132 | return this.jiraClient.makeRequest(options, callback); 133 | }; 134 | } -------------------------------------------------------------------------------- /types/api/issue.d.ts: -------------------------------------------------------------------------------- 1 | import { Callback } from "../callback"; 2 | 3 | export interface HistoryMetadataParticipant { 4 | [key: string]: any; 5 | id?: string; 6 | displayName?: string; 7 | displayNameKey?: string; 8 | type?: string; 9 | avatarUrl?: string; 10 | url?: string; 11 | } 12 | 13 | export interface HistoryMetadata { 14 | [key: string]: any; 15 | type?: string; 16 | description?: string; 17 | descriptionKey?: string; 18 | activityDescription?: string; 19 | activityDescriptionKey?: string; 20 | emailDescription?: string; 21 | emailDescriptionKey?: string; 22 | actor?: HistoryMetadataParticipant; 23 | generator?: HistoryMetadataParticipant; 24 | cause?: HistoryMetadataParticipant; 25 | extraData?: any; 26 | } 27 | 28 | export class Issue { 29 | [method: string]: any; 30 | 31 | editIssue( 32 | opts: { 33 | issueKey?: string | number; 34 | issueId?: string | number; 35 | notifyUsers?: boolean; 36 | overrideScreenSecurity?: boolean; 37 | overrideEditableFlag?: boolean; 38 | issue?: { 39 | [key: string]: any; 40 | transition?: { 41 | [key: string]: any; 42 | id?: string | number; 43 | }; 44 | fields?: any; 45 | update?: any; 46 | historyMetadata?: HistoryMetadata, 47 | properties: any[]; 48 | } 49 | }, 50 | callback?: Callback 51 | ): Promise; 52 | 53 | addComment( 54 | opts: { 55 | [key: string]: any; 56 | issueId?: string; 57 | issueKey?: string; 58 | expand?: string; 59 | body?: string; 60 | visibility?: { 61 | [key: string]: any; 62 | type?: string | 'role' | 'group'; 63 | value?: string; 64 | }; 65 | properties?: any[]; 66 | }, 67 | callback?: Callback 68 | ): Promise; 69 | 70 | deleteComment( 71 | opts: { 72 | issueId?: string | number; 73 | issueKey?: string | number; 74 | commentId: string | number; 75 | }, 76 | callback?: Callback 77 | ): Promise; 78 | 79 | getChangelog( 80 | opts: { 81 | issueId?: number | string, 82 | issueKey?: number | string, 83 | startAt?: number, 84 | maxResults?: number 85 | }, 86 | callback?: Callback 87 | ): Promise; 88 | 89 | addWorkLog( 90 | opts: { 91 | [key: string]: any, 92 | issueId?: number | string, 93 | issueKey?: number | string, 94 | notifyUsers?: boolean, 95 | adjustEstimate?: 'auto' | 'new' | 'manual' | 'leave', 96 | newEstimate?: string, 97 | reduceBy?: string, 98 | expand?: string, 99 | overrideEditableFlag?: boolean, 100 | comment?: any, 101 | visibility?: { 102 | [key: string]: any, 103 | type?: 'group' | 'role', 104 | value?: string 105 | }, 106 | started?: string, 107 | timeSpent?: string, 108 | timeSpentSeconds?: number | string, 109 | properties?: Array<{ 110 | [key: string]: any 111 | }> 112 | }, 113 | callback?: Callback 114 | ): Promise; 115 | 116 | getWorklog( 117 | opts: { 118 | issueId?: number | string, 119 | issueKey?: number | string, 120 | id: string, 121 | expand?: string 122 | }, 123 | callback?: Callback 124 | ): Promise; 125 | 126 | updateWorklog( 127 | opts: { 128 | [key: string]: any, 129 | issueId?: number | string, 130 | issueKey?: number | string, 131 | id: string, 132 | notifyUsers?: boolean, 133 | adjustEstimate?: 'auto' | 'new' | 'manual' | 'leave', 134 | newEstimate?: string, 135 | expand?: string, 136 | overrideEditableFlag?: boolean, 137 | comment?: any, 138 | visibility?: { 139 | [key: string]: any, 140 | type?: 'group' | 'role', 141 | value?: string 142 | }, 143 | started?: string, 144 | timeSpent?: string, 145 | timeSpentSeconds?: number | string, 146 | properties?: Array<{ 147 | [key: string]: any 148 | }> 149 | }, 150 | callback?: Callback 151 | ): Promise; 152 | 153 | deleteWorklog( 154 | opts: { 155 | issueId?: number | string, 156 | issueKey?: number | string, 157 | id: string, 158 | notifyUsers?: boolean, 159 | adjustEstimate?: string, 160 | newEstimate?: string, 161 | increaseBy?: string, 162 | overrideEditableFlag?: boolean 163 | }, 164 | callback?: Callback 165 | ): Promise; 166 | 167 | addAttachment( 168 | opts: { 169 | filename: string | string[], 170 | issueId?: string | number, 171 | issueKey?: string | number, 172 | headers?: { 173 | 'X-Atlassian-Token'?: string, 174 | charset?: string, 175 | [key: string]: any 176 | } 177 | }, 178 | callback?: Callback 179 | ): Promise>; 204 | } 205 | -------------------------------------------------------------------------------- /api/comment.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | 3 | var errorStrings = require('./../lib/error'); 4 | 5 | module.exports = CommentClient; 6 | 7 | /** 8 | * Used to access Jira REST endpoints in '/rest/api/2/comment' 9 | * @constructor CommentClient 10 | * @param {JiraClient} jiraClient 11 | */ 12 | function CommentClient(jiraClient) { 13 | this.jiraClient = jiraClient; 14 | 15 | /** 16 | * Returns the keys of all properties for the comment identified by the key or by the id. 17 | * 18 | * @method getCommentPropertyKeys 19 | * @memberOf CommentClient# 20 | * @param opts The options passed in the request to the API. 21 | * @param opts.commentId The id of the comment from which keys will be returned. 22 | * @param [callback] Called when the keys have been retrieved. 23 | * @return {Promise} Resolved when the keys have been retrieved. 24 | */ 25 | this.getCommentPropertyKeys = function (opts, callback) { 26 | var options = this.buildRequestOptions(opts, '', 'GET'); 27 | return this.jiraClient.makeRequest(options, callback); 28 | }; 29 | 30 | /** 31 | * Sets the value of the specified comment's property. 32 | * 33 | * You can use this resource to store a custom data against the comment identified by the key or by the id. The 34 | * user who stores the data is required to have permissions to administer the comment. 35 | * 36 | * @method setCommentProperty 37 | * @memberOf CommentClient# 38 | * @param opts The options passed in the request to the API. 39 | * @param opts.commentId The id of the comment from which keys will be returned. 40 | * @param opts.propertyKey The key of the property to be edited. 41 | * @param opts.propertyValue The new value of the property. 42 | * @param [callback] Called when the property has been edited. 43 | * @return {Promise} Resolved when the property has been edited. 44 | */ 45 | this.setCommentProperty = function (opts, callback) { 46 | if (!opts.propertyKey) { 47 | throw new Error(errorStrings.NO_COMMENT_PROPERTY_KEY_ERROR); 48 | } else if (!opts.propertyValue) { 49 | throw new Error(errorStrings.NO_COMMENT_PROPERTY_VALUE_ERROR); 50 | } 51 | var options = this.buildRequestOptions(opts, '/' + opts.propertyKey, 'PUT', opts.propertyValue); 52 | return this.jiraClient.makeRequest(options, callback, 'Property Edited'); 53 | }; 54 | 55 | /** 56 | * Returns the value of the property with a given key from the comment identified by the key or by the id. The user 57 | * who retrieves the property is required to have permissions to read the comment. 58 | * 59 | * @method getCommentProperty 60 | * @memberOf CommentClient# 61 | * @param opts The options passed in the request to the API. 62 | * @param opts.commentId The id of the comment from which keys will be returned. 63 | * @param opts.propertyKey The key of the property to be edited. 64 | * @param [callback] Called when the property has been retrieved. 65 | * @return {Promise} Resolved when the property has been retrieved. 66 | */ 67 | this.getCommentProperty = function (opts, callback) { 68 | if (!opts.propertyKey) { 69 | throw new Error(errorStrings.NO_COMMENT_PROPERTY_KEY_ERROR); 70 | } 71 | var options = this.buildRequestOptions(opts, '/' + opts.propertyKey, 'GET'); 72 | return this.jiraClient.makeRequest(options, callback); 73 | }; 74 | 75 | /** 76 | * Removes the property from the comment identified by the key or by the id. Ths user removing the property is 77 | * required to have permissions to administer the comment. 78 | * 79 | * @method deleteCommentProperty 80 | * @memberOf CommentClient# 81 | * @param opts The options passed in the request to the API. 82 | * @param opts.commentId The id of the comment from which keys will be returned. 83 | * @param opts.propertyKey The key of the property to be edited. 84 | * @param [callback] Called when the property has been retrieved. 85 | * @return {Promise} Resolved when the property has been retrieved. 86 | */ 87 | this.deleteCommentProperty = function (opts, callback) { 88 | if (!opts.propertyKey) { 89 | throw new Error(errorStrings.NO_COMMENT_PROPERTY_KEY_ERROR); 90 | } 91 | var options = this.buildRequestOptions(opts, '/' + opts.propertyKey, 'DELETE'); 92 | return this.jiraClient.makeRequest(options, callback, 'Comment property deleted'); 93 | }; 94 | 95 | /** 96 | * Build out the request options necessary to make a particular API call. 97 | * 98 | * @private 99 | * @method buildRequestOptions 100 | * @memberOf CommentClient# 101 | * @param {Object} opts The arguments passed to the method. 102 | * @param {string} path The path of the endpoint following /issue/{idOrKey} 103 | * @param {string} method The request method. 104 | * @param {Object} [body] The request body, if any. 105 | * @param {Object} [qs] The querystring, if any. opts.expand and opts.fields arrays will be automagically added. 106 | * @returns {{uri: string, method: string, body: Object, qs: Object, followAllRedirects: boolean, json: boolean}} 107 | */ 108 | this.buildRequestOptions = function (opts, path, method, body, qs) { 109 | if (!opts.commentId) { 110 | throw new Error(errorStrings.NO_COMMENT_ID); 111 | } 112 | var basePath = '/comment/' + opts.commentId + "/properties"; 113 | if (!qs) qs = {}; 114 | if (!body) body = {}; 115 | 116 | if (opts.fields) { 117 | qs.fields = ''; 118 | opts.fields.forEach(function (field) { 119 | qs.fields += field + ',' 120 | }); 121 | } 122 | 123 | if (opts.expand) { 124 | qs.expand = ''; 125 | opts.expand.forEach(function (ex) { 126 | qs.expand += ex + ',' 127 | }); 128 | } 129 | 130 | return { 131 | uri: this.jiraClient.buildURL(basePath + path), 132 | method: method, 133 | body: body, 134 | qs: qs, 135 | followAllRedirects: true, 136 | json: true 137 | }; 138 | } 139 | } -------------------------------------------------------------------------------- /api/issueType.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | 3 | module.exports = IssueTypeClient; 4 | 5 | /** 6 | * Used to access Jira REST endpoints in '/rest/api/2/issuetype' 7 | * 8 | * @param {JiraClient} jiraClient 9 | * @constructor IssueTypeClient 10 | */ 11 | function IssueTypeClient(jiraClient) { 12 | this.jiraClient = jiraClient; 13 | 14 | /** 15 | * Returns a list of all issue types visible to the user 16 | * 17 | * @method getAllIssueTypes 18 | * @memberOf IssueTypeClient# 19 | * @param {Object} [opts] Ignored 20 | * @param {callback} [callback] Called when the issue types have been retrieved. 21 | * @return {Promise} Resolved when the issue types have been retrieved. 22 | */ 23 | this.getAllIssueTypes = function (opts, callback) { 24 | var options = { 25 | uri: this.jiraClient.buildURL('/issuetype'), 26 | method: 'GET', 27 | json: true, 28 | followAllRedirects: true 29 | }; 30 | 31 | return this.jiraClient.makeRequest(options, callback); 32 | }; 33 | 34 | /** 35 | * Creates an issue type from a JSON representation and adds the issue newly 36 | * created issue type to the default issue type scheme. 37 | * 38 | * @method createIssueType 39 | * @memberOf IssueTypeClient# 40 | * @param {Object} opts Object containing details of the new issueType. 41 | * @param {string} opts.name The name of the issue type 42 | * @param {string} [opts.description] The description of the issue type 43 | * @param {'subtype'|'standard'} [opts.type] The type of the issue type 44 | * @param {callback} [callback] Called when the issue type has been created. 45 | * @return {Promise} Resolved when the issue type has been created. 46 | */ 47 | this.createIssueType = function (opts, callback) { 48 | var options = { 49 | uri: this.jiraClient.buildURL('/issuetype'), 50 | method: 'POST', 51 | json: true, 52 | followAllRedirects: true, 53 | body: opts, 54 | }; 55 | 56 | return this.jiraClient.makeRequest(options, callback); 57 | }; 58 | 59 | /** 60 | * Get a full representation of the issue type that has the given id. 61 | * 62 | * @method getIssueType 63 | * @memberOf IssueTypeClient# 64 | * @param {Object} opts The options sent to the Jira API 65 | * @param {string} opts.issueTypeId A String containing an issue type id 66 | * @param {callback} [callback] Called when the issue type has been retrieved. 67 | * @return {Promise} Resolved when the issue type has been retrieved. 68 | */ 69 | this.getIssueType = function (opts, callback) { 70 | var options = { 71 | uri: this.jiraClient.buildURL('/issuetype/' + opts.issueTypeId), 72 | method: 'GET', 73 | json: true, 74 | followAllRedirects: true 75 | }; 76 | 77 | return this.jiraClient.makeRequest(options, callback); 78 | }; 79 | 80 | /** 81 | * Updates the specified issue type from a JSON representation. 82 | * 83 | * @method updateIssueType 84 | * @memberOf IssueTypeClient# 85 | * @param {Object} opts The options sent to the Jira API 86 | * @param {string} opts.issueTypeId ID of the issue type to update. 87 | * @param {Object} opts.issueType Object containing details of the issueType to be updated. 88 | * @param {string} [opts.issueType.name] The name of the issue type 89 | * @param {string} [opts.issueType.avatarId] The id of the avatar for the issue type 90 | * @param {string} [opts.issueType.description] The description of the issue type 91 | * @param {callback} [callback] Called when the issue type has been updated. 92 | * @return {Promise} Resolved when the issue type has been updated. 93 | */ 94 | this.updateIssueType = function (opts, callback) { 95 | var options = { 96 | uri: this.jiraClient.buildURL('/issuetype/' + opts.issueTypeId), 97 | method: 'PUT', 98 | json: true, 99 | followAllRedirects: true, 100 | body: opts.issueType, 101 | }; 102 | 103 | return this.jiraClient.makeRequest(options, callback); 104 | }; 105 | 106 | /** 107 | * Deletes the specified issue type. 108 | * If the issue type has any associated issues, these issues will be 109 | * migrated to the alternative issue type specified in the parameter. 110 | * You can determine the alternative issue types by calling the /rest/api/2/issuetype/{id}/alternatives resource. 111 | * 112 | * @method deleteIssueType 113 | * @memberOf IssueTypeClient# 114 | * @param {Object} opts The options to send to the JIRA API 115 | * @param {string} opts.issueTypeId ID of the issueType to be deleted. 116 | * @param {string} [opts.alternativeIssueTypeId] the id of an issue type to which issues 117 | * associated with the removed issue type will be migrated. 118 | * @param {callback} [callback] Called when the issue type has been deleted. 119 | * @return {Promise} Resolved when the issue type has been deleted. 120 | */ 121 | this.deleteIssueType = function (opts, callback) { 122 | var options = { 123 | uri: this.jiraClient.buildURL('/issuetype/' + opts.issueTypeId), 124 | method: 'DELETE', 125 | json: true, 126 | followAllRedirects: true, 127 | qs: { 128 | alternativeIssueTypeId: opts.alternativeIssueTypeId, 129 | }, 130 | }; 131 | 132 | return this.jiraClient.makeRequest(options, callback); 133 | }; 134 | 135 | /** 136 | * Returns a list of all alternative issue types for the given issue type id. 137 | * The list will contain these issues types, to which issues assigned to the given 138 | * issue type can be migrated. The suitable alternatives are issue types which are 139 | * assigned to the same workflow, the same field configuration and the same screen scheme. 140 | * 141 | * @method getAlternativeIssueTypes 142 | * @memberOf IssueTypeClient# 143 | * @param {Object} opts The options sent to the Jira API 144 | * @param {string} opts.issueTypeId A String containing an issue type id 145 | * @param {callback} [callback] Called when the issue type has been retrieved. 146 | * @return {Promise} Resolved when the issue type has been retrieved. 147 | */ 148 | this.getAlternativeIssueTypes = function (opts, callback) { 149 | var options = { 150 | uri: this.jiraClient.buildURL('/issuetype/' + opts.issueTypeId + '/alternatives'), 151 | method: 'GET', 152 | json: true, 153 | followAllRedirects: true 154 | }; 155 | 156 | return this.jiraClient.makeRequest(options, callback); 157 | }; 158 | } 159 | -------------------------------------------------------------------------------- /api/roles.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | 3 | module.exports = RoleClient; 4 | 5 | /** 6 | * Used to access Jira REST endpoints in '/rest/api/2/role' 7 | * 8 | * @param {JiraClient} jiraClient 9 | * @constructor RoleClient 10 | */ 11 | function RoleClient(jiraClient) { 12 | this.jiraClient = jiraClient; 13 | 14 | /** 15 | * Get all the ProjectRoles available in Jira. Currently this list is global. 16 | * 17 | * @method getAll 18 | * @memberOf RoleClient# 19 | * @param opts The request options sent to the Jira API. 20 | * @param [callback] Called when the permissions have been returned. 21 | * @return {Promise} Resolved when the permissions have been returned. 22 | */ 23 | this.getAll = function (opts, callback) { 24 | var options = { 25 | uri: this.jiraClient.buildURL('/role'), 26 | method: 'GET', 27 | json: true, 28 | followAllRedirects: true 29 | }; 30 | 31 | return this.jiraClient.makeRequest(options, callback); 32 | } 33 | 34 | /** 35 | * Creates a new ProjectRole to be available in Jira. 36 | * The created role does not have any default actors assigned. 37 | * 38 | * @method createRole 39 | * @memberOf RoleClient# 40 | * @param opts The request options sent to the Jira API. 41 | * @param opts.role See {@link https://developer.atlassian.com/cloud/jira/platform/rest/#api-api-2-role-post} 42 | * @param [callback] Called when the scheme has been created. 43 | * @return {Promise} Resolved when the scheme has been created. 44 | */ 45 | this.createRole = function (opts, callback) { 46 | var options = { 47 | uri: this.jiraClient.buildURL('/role'), 48 | method: 'POST', 49 | json: true, 50 | followAllRedirects: true, 51 | body: opts.role 52 | }; 53 | 54 | return this.jiraClient.makeRequest(options, callback); 55 | } 56 | 57 | /** 58 | * Get a specific ProjectRole available in Jira. 59 | * 60 | * @method getRoleById 61 | * @memberOf RoleClient# 62 | * @param opts The request options sent to the Jira API. 63 | * @param [callback] Called when the permissions have been returned. 64 | * @return {Promise} Resolved when the permissions have been returned. 65 | */ 66 | this.getRoleById = function (opts, callback) { 67 | var options = { 68 | uri: this.jiraClient.buildURL('/role/' + opts.roleId), 69 | method: 'GET', 70 | json: true, 71 | followAllRedirects: true, 72 | }; 73 | 74 | return this.jiraClient.makeRequest(options, callback); 75 | }; 76 | 77 | /** 78 | * Fully updates a roles. Both name and description must be given. 79 | * 80 | * @method updateRole 81 | * @memberOf RoleClient# 82 | * @param opts The request options sent to the Jira API. 83 | * @param opts.roldId Identifier for teh role. 84 | * @param opts.role Object containing the name and description to be updated. 85 | * @param [callback] Called when the permissions have been returned. 86 | * @return {Promise} Resolved when the permissions have been returned. 87 | */ 88 | this.updateRole = function (opts, callback) { 89 | var options = { 90 | uri: this.jiraClient.buildURL('/role/' + opts.roleId), 91 | method: 'PUT', 92 | json: true, 93 | followAllRedirects: true, 94 | body: opts.role, 95 | }; 96 | 97 | return this.jiraClient.makeRequest(options, callback); 98 | }; 99 | 100 | /** 101 | * Deletes a role. May return 403 in the future 102 | * 103 | * @method deleteRole 104 | * @memberOf RoleClient# 105 | * @param {Object} opts The request options sent to the Jira API. 106 | * @param {String} opts.roldId Identifier for the role. 107 | * @param {String} opts.swap if given, removes a role even if it is used in scheme by replacing the role with the given one 108 | * @param [callback] Called when the permissions have been returned. 109 | * @return {Promise} Resolved when the permissions have been returned. 110 | */ 111 | this.deleteRole = function (opts, callback) { 112 | var options = { 113 | uri: this.jiraClient.buildURL('/role/' + opts.roleId), 114 | method: 'DELETE', 115 | json: true, 116 | followAllRedirects: true, 117 | qs: { 118 | swap: opts.swap 119 | } 120 | }; 121 | 122 | return this.jiraClient.makeRequest(options, callback); 123 | }; 124 | 125 | /** 126 | * Gets default actors for the given role. 127 | * 128 | * @method getActors 129 | * @memberOf RoleClient# 130 | * @param {Object} opts The request options sent to the Jira API. 131 | * @param {String} opts.roldId Identifier for the role. 132 | * @param [callback] Called when the permissions have been returned. 133 | * @return {Promise} Resolved when the permissions have been returned. 134 | */ 135 | this.getActors = function (opts, callback) { 136 | var options = { 137 | uri: this.jiraClient.buildURL('/role/' + opts.roleId + '/actors'), 138 | method: 'GET', 139 | json: true, 140 | followAllRedirects: true, 141 | }; 142 | 143 | return this.jiraClient.makeRequest(options, callback); 144 | }; 145 | 146 | /** 147 | * Adds default actors to the given role. 148 | * The request data should contain a list of usernames or a list of groups to add. 149 | * 150 | * @method addActors 151 | * @memberOf RoleClient# 152 | * @param {Object} opts The request options sent to the Jira API. 153 | * @param {String} opts.roldId Identifier for the role. 154 | * @param {Array} opts.group Array of group ids. 155 | * @param {Array} opts.user Array of user ids. 156 | * @param [callback] Called when the permissions have been returned. 157 | * @return {Promise} Resolved when the permissions have been returned. 158 | */ 159 | this.addActors = function (opts, callback) { 160 | var options = { 161 | uri: this.jiraClient.buildURL('/role/' + opts.roleId + '/actors'), 162 | method: 'POST', 163 | json: true, 164 | followAllRedirects: true, 165 | body: { 166 | user: opts.user, 167 | group: opts.group, 168 | }, 169 | }; 170 | 171 | return this.jiraClient.makeRequest(options, callback); 172 | }; 173 | 174 | /** 175 | * Removes default actor from the given role. 176 | * 177 | * @method removeActor 178 | * @memberOf RoleClient# 179 | * @param {Object} opts The request options sent to the Jira API. 180 | * @param {String} opts.roldId Identifier for the role. 181 | * @param {String} opts.group group id. 182 | * @param {String} opts.user user id. 183 | * @param [callback] Called when the permissions have been returned. 184 | * @return {Promise} Resolved when the permissions have been returned. 185 | */ 186 | this.removeActor = function (opts, callback) { 187 | var options = { 188 | uri: this.jiraClient.buildURL('/role/' + opts.roleId + '/actors'), 189 | method: 'DELETE', 190 | json: true, 191 | followAllRedirects: true, 192 | qs: { 193 | user: opts.user, 194 | group: opts.group, 195 | }, 196 | }; 197 | 198 | return this.jiraClient.makeRequest(options, callback); 199 | }; 200 | } -------------------------------------------------------------------------------- /api/group.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | 3 | module.exports = GroupClient; 4 | 5 | /** 6 | * Used to access Jira REST endpoints in '/rest/api/2/group' 7 | * 8 | * These are considered experimental according to the Jira Docs, use at your own risk. 9 | * 10 | * @param {JiraClient} jiraClient 11 | * @constructor GroupClient 12 | */ 13 | function GroupClient(jiraClient) { 14 | this.jiraClient = jiraClient; 15 | 16 | /** 17 | * Creates a group by given group parameter Returns REST representation for the requested group. 18 | * 19 | * @method createGroup 20 | * @memberOf GroupClient# 21 | * @param opts The request options sent to jira 22 | * @param opts.group The group to create. See {@link https://docs.atlassian.com/jira/REST/latest/#d2e2011} 23 | * @param [callback] Called when the group is created 24 | * @return {Promise} Resolved when the group is created 25 | */ 26 | this.createGroup = function (opts, callback) { 27 | var options = { 28 | uri: this.jiraClient.buildURL('/group'), 29 | method: 'POST', 30 | json: true, 31 | followAllRedirects: true, 32 | body: opts.group 33 | }; 34 | 35 | return this.jiraClient.makeRequest(options, callback); 36 | }; 37 | 38 | /** 39 | * Returns REST representation for the requested group. Allows to get list of active users belonging to the 40 | * specified group and its subgroups if "users" expand option is provided. You can page through users list by using 41 | * indexes in expand param. For example to get users from index 10 to index 15 use "users[10:15]" expand value. 42 | * This will return 6 users (if there are at least 16 users in this group). Indexes are 0-based and inclusive. 43 | * DEPRECATED. This resource is deprecated, please use group/member API instead. (15-Feb-2018) 44 | * 45 | * @method getGroup 46 | * @memberOf GroupClient# 47 | * @param opts The request options sent to the Jira API 48 | * @param opts.groupName A name of requested group. 49 | * @param opts.expand Array of fields to expand. Currently only available expand is "users". 50 | * @param [callback] Called when the group is retrieved. 51 | * @return {Promise} Resolved when the group is retrieved. 52 | */ 53 | this.getGroup = function (opts, callback) { 54 | var qs = { 55 | groupname: opts.groupName 56 | }; 57 | 58 | if (opts.expand) { 59 | qs.expand = ''; 60 | opts.expand.forEach(function (ex) { 61 | qs.expand += ex + ',' 62 | }); 63 | } 64 | 65 | var options = { 66 | uri: this.jiraClient.buildURL('/group'), 67 | method: 'GET', 68 | json: true, 69 | followAllRedirects: true, 70 | qs: qs 71 | }; 72 | 73 | return this.jiraClient.makeRequest(options, callback); 74 | }; 75 | 76 | /** 77 | * This resource returns a paginated list of users who are members of the specified group and its subgroups. 78 | * Users in the page are ordered by user names. 79 | * User of this resource is required to have sysadmin or admin permissions. 80 | * 81 | * @method getMembers 82 | * @memberOf GroupClient# 83 | * @param {Object} opts The request options sent to the Jira API 84 | * @param {String} opts.groupName A name of requested group. 85 | * @param {Boolean} opts.includeInactiveUsers inactive users will be included in the response if set to true. Default false. 86 | * @param {Number} opts.startAt the index of the first user in group to return (0 based). 87 | * @param {Number} opts.maxResults the maximum number of users to return (max 50). 88 | * @param [callback] Called when the group is retrieved. 89 | * @return {Promise} Resolved when the group is retrieved. 90 | */ 91 | this.getMembers = function (opts, callback) { 92 | var qs = { 93 | groupname: opts.groupName, 94 | includeInactiveUsers: opts.includeInactiveUsers, 95 | startAt: opts.startAt, 96 | maxResults: opts.maxResults, 97 | }; 98 | 99 | var options = { 100 | uri: this.jiraClient.buildURL('/group/member'), 101 | method: 'GET', 102 | json: true, 103 | followAllRedirects: true, 104 | qs: qs 105 | }; 106 | 107 | return this.jiraClient.makeRequest(options, callback); 108 | }; 109 | 110 | /** 111 | * Adds given user to a group. Returns the current state of the group. 112 | * 113 | * @method addUserToGroup 114 | * @memberOf GroupClient# 115 | * @param {Object} opts The request options sent to the Jira API 116 | * @param {string} opts.groupName A name of requested group. 117 | * @param {string} opts.userName The name of the user to add to the group. 118 | * @param [callback] Called when the user has been added to the group. 119 | * @return {Promise} Resolved when the user has been added to the group. 120 | */ 121 | this.addUserToGroup = function (opts, callback) { 122 | var options = { 123 | uri: this.jiraClient.buildURL('/group/user'), 124 | method: 'POST', 125 | json: true, 126 | followAllRedirects: true, 127 | qs: { 128 | groupname: opts.groupName 129 | }, 130 | body: { 131 | name: opts.userName 132 | } 133 | }; 134 | 135 | return this.jiraClient.makeRequest(options, callback); 136 | }; 137 | 138 | /** 139 | * Removes given user from a group. Returns no content 140 | * 141 | * @method removeUserFromGroup 142 | * @memberOf GroupClient# 143 | * @param {Object} opts The request options sent to the Jira API 144 | * @param {string} opts.groupName A name of requested group. 145 | * @param {string} opts.userName The name of the user to add to the group. 146 | * @param [callback] Called when the user has been added to the group. 147 | * @return {Promise} Resolved when the user has been added to the group. 148 | */ 149 | this.removeUserFromGroup = function (opts, callback) { 150 | var options = { 151 | uri: this.jiraClient.buildURL('/group/user'), 152 | method: 'DELETE', 153 | json: true, 154 | followAllRedirects: true, 155 | qs: { 156 | groupname: opts.groupName, 157 | username: opts.userName 158 | } 159 | }; 160 | 161 | return this.jiraClient.makeRequest(options, callback, 'User Removed from Group'); 162 | }; 163 | 164 | /** 165 | * Deletes a group by given group parameter. Returns no content 166 | * 167 | * @method deleteGroup 168 | * @memberOf GroupClient# 169 | * @param {Object} opts The request options sent to the Jira API 170 | * @param {string} opts.groupName A group to delete. 171 | * @param {string} [opts.swapGroup] A group to transfer visibility restrictions of the group that is being deleted 172 | * @param [callback] Called when the group has been deleted. 173 | * @return {Promise} Resolved when the group has been deleted. 174 | */ 175 | this.deleteGroup = function (opts, callback) { 176 | var options = { 177 | uri: this.jiraClient.buildURL('/group'), 178 | method: 'DELETE', 179 | json: true, 180 | followAllRedirects: true, 181 | qs: { 182 | groupname: opts.groupName, 183 | swapGroup: opts.swapGroup 184 | } 185 | }; 186 | 187 | return this.jiraClient.makeRequest(options, callback, 'Group Deleted'); 188 | }; 189 | } -------------------------------------------------------------------------------- /lib/oauth_util.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | 3 | // npm packages 4 | var Oauth = require('oauth'); 5 | 6 | // Core packages 7 | var url = require('url'); 8 | 9 | // Custom Packages 10 | var errorStrings = require('./error'); 11 | 12 | /** 13 | * @namespace OauthUtil 14 | */ 15 | 16 | /** 17 | * Attempts to get an OAuth verification URL using the given API configuration. 18 | * 19 | * @memberOf OauthUtil 20 | * @param {Object} config The information needed to access the Jira API 21 | * @param {string} config.host The hostname of the Jira API. 22 | * @param {string} [config.protocol=https] - The protocol used to accses the Jira API. 23 | * @param {number} [config.port=443] - The port number used to connect to Jira. 24 | * @param {string} [config.path_prefix="/"] The prefix to use in front of the path, if Jira isn't at "/" 25 | * @param {string} [config.version=2] - The version of the Jira API to which you will be connecting. Currently, only 26 | * version 2 is supported. 27 | * @param {Object} config.oauth The oauth information 28 | * @param {string} config.oauth.consumer_key The consumer key of the application accessing Jira. 29 | * @param {string} config.oauth.private_key The private key of the application accessing Jira. 30 | * @param {string} [config.oauth.callback_url] The callback URL to be called after the token is generated. If this is 31 | * not included, the user will be given a verification code after authorizing the token, instead of Jira making a 32 | * callback to the application. 33 | * @param {OauthUtil~getOauthUrlCallback} callback The function called when the URL has been retrieved. 34 | */ 35 | exports.getAuthorizeURL = function (config, callback) { 36 | var prefix = config.path_prefix ? config.path_prefix : ''; 37 | var AUTH_TOKEN_APPEND = '/oauth/authorize'; 38 | var SERVLET_BASE_URL = prefix + '/plugins/servlet'; 39 | 40 | var authURL = url.format({ 41 | protocol: config.protocol ? config.protocol : 'https', 42 | hostname: config.host, 43 | port: config.port ? config.port : null, 44 | pathname: SERVLET_BASE_URL + AUTH_TOKEN_APPEND 45 | }); 46 | 47 | var oauth = generateOAuthObject(config); 48 | 49 | oauth.getOAuthRequestToken(function (err, token, token_secret) { 50 | if (err) { 51 | return callback(err); 52 | } 53 | return callback(null, { url: authURL + "?oauth_token=" + token, token: token, token_secret: token_secret }); 54 | }); 55 | }; 56 | 57 | /** 58 | * Given an OAuth token, the token secret, and an access verification code (provided by Jira), swap an OAuth request 59 | * token with an OAuth access token. 60 | * 61 | * @memberOf OauthUtil 62 | * @param {Object} config The information needed to access the Jira API 63 | * @param {string} config.host The hostname of the Jira API. 64 | * @param {string} [config.protocol=https] - The protocol used to accses the Jira API. 65 | * @param {number} [config.port=443] - The port number used to connect to Jira. 66 | * @param {string} [config.version=2] - The version of the Jira API to which you will be connecting. Currently, only 67 | * version 2 is supported. 68 | * @param {Object} config.oauth The oauth information 69 | * @param {string} config.oauth.consumer_key The consumer key of the application accessing Jira. 70 | * @param {string} config.oauth.private_key The private key of the application accessing Jira. 71 | * @param {string} config.oauth.token The OAuth Token supplied by Jira. 72 | * @param {string} config.oauth.token_secret The OAuth Token secret supplied by Jira. 73 | * @param {string} config.oauth.oauth_verifier The verified code given to the user after authorizing the OAuth token. 74 | * @param {OauthUtil~swapRequestTokenCallback} callback The function called when the token has been swapped. 75 | */ 76 | exports.swapRequestTokenWithAccessToken = function (config, callback) { 77 | if (!config.oauth.oauth_verifier) { 78 | throw new Error(errorStrings.NO_VERIFIER_ERROR); 79 | } 80 | 81 | var oauth = generateOAuthObject(config); 82 | 83 | var token = config.oauth.token; 84 | var secret = config.oauth.token_secret; 85 | var verifier = config.oauth.oauth_verifier; 86 | 87 | oauth.getOAuthAccessToken(token, secret, verifier, callback); 88 | }; 89 | 90 | /** 91 | * Utility function to generate an OAuth object. 92 | * 93 | * @memberOf OauthUtil 94 | * @param {Object} config The information needed to access the Jira API 95 | * @param {string} config.host The hostname of the Jira API. 96 | * @param {string} [config.protocol=https] - The protocol used to accses the Jira API. 97 | * @param {number} [config.port=443] - The port number used to connect to Jira. 98 | * @param {string} [config.path_prefix="/"] The prefix to use in front of the path, if Jira isn't at "/" 99 | * @param {string} [config.version=2] - The version of the Jira API to which you will be connecting. Currently, only 100 | * version 2 is supported. 101 | * @param {Object} config.oauth The oauth information 102 | * @param {string} config.oauth.consumer_key The consumer key of the application accessing Jira. 103 | * @param {string} config.oauth.private_key The private key of the application accessing Jira. 104 | * @param {string} [config.oauth.callback_url] The callback URL to be called after the token is generated. If this is 105 | * not included, the user will be given a verification code after authorizing the token, instead of Jira making a 106 | * callback to the application. 107 | * 108 | * @returns {exports.OAuth} The generated object. 109 | */ 110 | function generateOAuthObject(config) { 111 | var prefix = config.path_prefix ? config.path_prefix : ''; 112 | var SERVLET_BASE_URL = prefix + '/plugins/servlet'; 113 | var REQ_TOKEN_APPEND = '/oauth/request-token'; 114 | 115 | var ACCESS_TOKEN_APPEND = '/oauth/access-token'; 116 | var sig = 'RSA-SHA1'; 117 | 118 | if (!config.host) { 119 | throw new Error(errorStrings.NO_HOST_ERROR); 120 | } else if (!config.oauth.consumer_key) { 121 | throw new Error(errorStrings.NO_CONSUMER_KEY_ERROR); 122 | } else if (!config.oauth.private_key) { 123 | throw new Error(errorStrings.NO_PRIVATE_KEY_ERROR); 124 | } 125 | 126 | var consumer_key = config.oauth.consumer_key; 127 | var private_key = config.oauth.private_key; 128 | 129 | var reqURL = url.format({ 130 | protocol: config.protocol ? config.protocol : 'https', 131 | hostname: config.host, 132 | port: config.port ? config.port : null, 133 | pathname: SERVLET_BASE_URL + REQ_TOKEN_APPEND 134 | }); 135 | 136 | var accessURL = url.format({ 137 | protocol: config.protocol ? config.protocol : 'https', 138 | hostname: config.host, 139 | port: config.port ? config.port : null, 140 | pathname: SERVLET_BASE_URL + ACCESS_TOKEN_APPEND 141 | }); 142 | 143 | var cb = config.oauth.callback_url ? config.oauth.callback_url : 'oob'; 144 | 145 | return new Oauth.OAuth(reqURL, accessURL, consumer_key, private_key, '1.0', cb, sig); 146 | } 147 | 148 | /** 149 | * Callback used by getOauthUrl. 150 | * @callback OauthUtil~getOauthUrlCallback 151 | * @param {*} error The error which occurred, if any. 152 | * @param {Object} oauth The OAuth information retrieved from the Jira API. 153 | * @param {String} oauth.url The URL that should be visited by the user to verify the OAuth access. 154 | * @param {String} oauth.token The OAuth Token retrieved from the Jira API. 155 | * @param {String} oauth.token_secret The OAuth Token Secret retrieved from the Jira API. 156 | */ 157 | 158 | /** 159 | * Callback used by swapRequestTokenWithAccessToken 160 | * @callback OauthUtil~swapRequestTokenCallback 161 | * @param {*} error The error which occurred, if any. 162 | * @param {string} access_token The access token retrieved from Jira. 163 | */ 164 | -------------------------------------------------------------------------------- /api/sprint.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | 3 | module.exports = AgileSprintClient; 4 | 5 | /** 6 | * Used to access Jira REST endpoints in '/rest/agile/1.0/sprint' 7 | * @param {JiraClient} jiraClient 8 | * @constructor AgileSprintClient 9 | */ 10 | function AgileSprintClient(jiraClient) { 11 | this.jiraClient = jiraClient; 12 | 13 | /** 14 | * Creates a sprint from a JSON representation. 15 | * 16 | * @method createSprint 17 | * @memberOf AgileSprintClient# 18 | * @param {Object} sprint The sprint data in the form of POST body to the 19 | * Jira API. 20 | * @param {callback} [callback] Called when the sprint has been created. 21 | * @return {Promise} Resolved when the sprint has been created. 22 | */ 23 | this.createSprint = function (sprint, callback) { 24 | var options = { 25 | uri: this.jiraClient.buildAgileURL('/sprint'), 26 | method: 'POST', 27 | followAllRedirects: true, 28 | json: true, 29 | body: sprint 30 | }; 31 | 32 | return this.jiraClient.makeRequest(options, callback); 33 | }; 34 | 35 | /** 36 | * Get a single sprint. 37 | * 38 | * @method getSprint 39 | * @memberOf AgileSprintClient# 40 | * @param {object} opts The request options sent to the Jira API. 41 | * @param {string} opts.sprintId The sprint id. 42 | * @param {string} [opts.filter] 43 | * @param {string} [opts.startAt] 44 | * @param {string} [opts.maxResults] 45 | * @param {callback} [callback] Called when the sprint has been retrieved. 46 | * @return {Promise} Resolved when the sprint has been retrieved. 47 | */ 48 | this.getSprint = function (opts, callback) { 49 | var options = { 50 | uri: this.jiraClient.buildAgileURL('/sprint/' + opts.sprintId), 51 | method: 'GET', 52 | json: true, 53 | followAllRedirects: true, 54 | qs: { 55 | filter: opts.filter, 56 | startAt: opts.startAt, 57 | maxResults: opts.maxResults 58 | } 59 | }; 60 | 61 | return this.jiraClient.makeRequest(options, callback); 62 | }; 63 | 64 | /** 65 | * Perform a full update of a sprint. 66 | * 67 | * @method updateSprint 68 | * @memberOf AgileSprintClient# 69 | * @param {Object} sprint The sprint data in the form of PUT body to the 70 | * Jira API. 71 | * @param {string} sprint.sprintId The id of the sprint. EX: 331 72 | * @param {callback} [callback] Called when the sprint has been updated. 73 | * @return {Promise} Resolved when the sprint has been updated. 74 | */ 75 | this.updateSprint = function (sprint, callback) { 76 | var sprintId = sprint.sprintId; 77 | delete sprint.sprintId; 78 | 79 | var options = { 80 | uri: this.jiraClient.buildAgileURL('/sprint/' + sprintId), 81 | method: 'PUT', 82 | followAllRedirects: true, 83 | json: true, 84 | body: sprint 85 | }; 86 | 87 | return this.jiraClient.makeRequest(options, callback); 88 | }; 89 | 90 | /** 91 | * Perform a partial update of a sprint. 92 | * 93 | * @method partiallyUpdateSprint 94 | * @memberOf AgileSprintClient# 95 | * @param {Object} sprint The sprint data in the form of POST body to the 96 | * Jira API. 97 | * @param {string} [sprint.sprintId] The id of the sprint. EX: 331. 98 | * @param {callback} [callback] Called when the sprint has been updated. 99 | * @return {Promise} Resolved when the sprint has been updated. 100 | */ 101 | this.partiallyUpdateSprint = function (sprint, callback) { 102 | var sprintId = sprint.sprintId; 103 | delete sprint.sprintId; 104 | 105 | var options = { 106 | uri: this.jiraClient.buildAgileURL('/sprint/' + sprintId), 107 | method: 'POST', 108 | followAllRedirects: true, 109 | json: true, 110 | body: sprint 111 | }; 112 | 113 | return this.jiraClient.makeRequest(options, callback); 114 | }; 115 | 116 | /** 117 | * Delete an existing sprint. 118 | * 119 | * @method deleteSprint 120 | * @memberOf AgileSprintClient# 121 | * @param {Object} opts The request options sent to the Jira API. 122 | * @param {string} opts.sprintId The id of the sprint. EX: 331 123 | * @param {string} [opts.filter] 124 | * @param {string} [opts.startAt] 125 | * @param {string} [opts.maxResults] 126 | * @param {callback} [callback] Called when the sprint is deleted. 127 | * @return {Promise} Resolved when the sprint is deleted. 128 | */ 129 | this.deleteSprint = function (opts, callback) { 130 | var options = { 131 | uri: this.jiraClient.buildAgileURL('/sprint/' + opts.sprintId), 132 | method: 'DELETE', 133 | json: true, 134 | followAllRedirects: true, 135 | qs: { 136 | filter: opts.filter, 137 | startAt: opts.startAt, 138 | maxResults: opts.maxResults 139 | } 140 | }; 141 | 142 | return this.jiraClient.makeRequest(options, callback); 143 | }; 144 | 145 | /** 146 | * Return all issues in a sprint, for a given sprint id. 147 | * 148 | * @method getSprintIssues 149 | * @memberOf AgileSprintClient# 150 | * @param {Object} opts The request options sent to the Jira API. 151 | * @param {string} opts.sprintId The sprint id. 152 | * @param {string} [opts.startAt] 153 | * @param {string} [opts.maxResults] 154 | * @param {string} [opts.jql] Filters results using a JQL query. 155 | * @param {boolean} [opts.validateQuery] Specifies whether to valide the JQL query. 156 | * @param {string} [opts.fields] The list of fields to return for each issue. 157 | * @param {string} [opts.expand] A comma-separated list of the parameters to expand. 158 | * @param {callback} [callback] Called when the issues are returned. 159 | * @return {Promise} Resolved when the issues are returned. 160 | */ 161 | this.getSprintIssues = function (opts, callback) { 162 | var options = { 163 | uri: this.jiraClient.buildAgileURL('/sprint/' + opts.sprintId + '/issue'), 164 | method: 'GET', 165 | json: true, 166 | followAllRedirects: true, 167 | qs: { 168 | startAt: opts.startAt, 169 | maxResults: opts.maxResults, 170 | jql: opts.jql, 171 | validateQuery: opts.validateQuery, 172 | fields: opts.fields, 173 | expand: opts.expand 174 | } 175 | }; 176 | 177 | return this.jiraClient.makeRequest(options, callback); 178 | }; 179 | 180 | /** 181 | * Move issues to a sprint, for a given sprint id. 182 | * 183 | * @method moveSprintIssues 184 | * @memberOf AgileSprintClient# 185 | * @param {Object} opts The issue data in the form of POST body to the 186 | * Jira API. 187 | * @param {string} opts.sprintId The sprint id. 188 | * @param {string[]} opts.issues Ids of the issues to move. 189 | * @param {string} [opts.rankBeforeIssue] 190 | * @param {string} [opts.rankAfterIssue] 191 | * @param {string} [opts.rankCustomField] 192 | * @param {callback} [callback] Called when the sprint has been retrieved. 193 | * @return {Promise} Resolved when the sprint has been retrieved. 194 | */ 195 | this.moveSprintIssues = function (opts, callback) { 196 | var sprintId = opts.sprintId; 197 | delete opts.sprintId; 198 | 199 | var options = { 200 | uri: this.jiraClient.buildAgileURL('/sprint/' + sprintId + '/issue'), 201 | method: 'POST', 202 | followAllRedirects: true, 203 | json: true, 204 | body: opts 205 | }; 206 | 207 | return this.jiraClient.makeRequest(options, callback); 208 | }; 209 | 210 | /** 211 | * Swap the position of the sprint (given by sprint id) with the second 212 | * sprint. 213 | * 214 | * @method swapSprint 215 | * @memberOf AgileSprintClient# 216 | * @param {Object} opts The data in the form of POST body to the Jira API. 217 | * @param {string} opts.sprintId The id of the sprint. EX: 311 218 | * @param {string} opts.sprintToSwapWith The id of the sprint. EX: 311 219 | * @param {callback} [callback] Called when the sprint has been retrieved. 220 | * @return {Promise} Resolved when the sprint has been retrieved. 221 | */ 222 | this.swapSprint = function (opts, callback) { 223 | var sprintId = opts.sprintId; 224 | delete opts.sprintId; 225 | 226 | var options = { 227 | uri: this.jiraClient.buildAgileURL('/sprint/' + sprintId + '/swap'), 228 | method: 'POST', 229 | followAllRedirects: true, 230 | json: true, 231 | body: opts 232 | }; 233 | 234 | return this.jiraClient.makeRequest(options, callback); 235 | }; 236 | 237 | } 238 | -------------------------------------------------------------------------------- /api/permission-scheme.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | 3 | module.exports = PermissionSchemeClient; 4 | 5 | /** 6 | * Used to access Jira REST endpoints in '/rest/api/2/permissionscheme' 7 | * 8 | * @param {JiraClient} jiraClient 9 | * @constructor PermissionSchemeClient 10 | */ 11 | function PermissionSchemeClient(jiraClient) { 12 | this.jiraClient = jiraClient; 13 | 14 | /** 15 | * Returns a list of all permission schemes. 16 | * 17 | * By default only shortened beans are returned. 18 | * If you want to include permissions of all the schemes, then specify the permissions expand parameter. 19 | * Permissions will be included also if you specify any other expand parameter. 20 | * 21 | * @method getAllPermissionSchemes 22 | * @memberOf PermissionSchemeClient# 23 | * @param {Object} opts The request options sent to the Jira API. 24 | * @param {String|Array} opts.expand 25 | * @param [callback] Called when the schemes have been returned. 26 | * @return {Promise} Resolved when the schemes have been returned. 27 | */ 28 | this.getAllPermissionSchemes = function (opts, callback) { 29 | var expand = opts.expand 30 | if (opts.expand && opts.expand instanceof Array) { 31 | expand = opts.expand.join(','); 32 | } 33 | var options = { 34 | uri: this.jiraClient.buildURL('/permissionscheme'), 35 | method: 'GET', 36 | json: true, 37 | followAllRedirects: true, 38 | qs: { 39 | expand: expand 40 | } 41 | }; 42 | 43 | return this.jiraClient.makeRequest(options, callback); 44 | } 45 | 46 | /** 47 | * Create a new permission scheme. This method can create schemes with a defined permission set, or without. 48 | * 49 | * @method createPermissionScheme 50 | * @memberOf PermissionSchemeClient# 51 | * @param opts The request options sent to the Jira API. 52 | * @param opts.scheme See {@link https://developer.atlassian.com/cloud/jira/platform/rest/#api-api-2-permissionscheme-post} 53 | * @param [callback] Called when the scheme has been created. 54 | * @return {Promise} Resolved when the scheme has been created. 55 | */ 56 | this.createPermissionScheme = function (opts, callback) { 57 | var options = { 58 | uri: this.jiraClient.buildURL('/permissionscheme'), 59 | method: 'POST', 60 | json: true, 61 | followAllRedirects: true, 62 | body: opts.scheme 63 | }; 64 | 65 | return this.jiraClient.makeRequest(options, callback); 66 | } 67 | 68 | /** 69 | * Get a PermissionScheme. This resource cannot be accessed anonymously. 70 | * 71 | * @method getPermissionScheme 72 | * @memberOf PermissionSchemeClient# 73 | * @param opts The request options sent to the Jira API 74 | * @param opts.schemeId The id of the scheme to retrieve. 75 | * @param {Object} opts.expand The fields to be expanded. 76 | * @param [callback] Called when the scheme has been retrieved. 77 | * @return {Promise} Resolved when the scheme has been retrieved. 78 | */ 79 | this.getPermissionScheme = function (opts, callback) { 80 | var expand = opts.expand 81 | if (opts.expand && opts.expand instanceof Array) { 82 | expand = opts.expand.join(','); 83 | } 84 | var options = { 85 | uri: this.jiraClient.buildURL('/permissionscheme/' + opts.schemeId), 86 | method: 'GET', 87 | json: true, 88 | followAllRedirects: true, 89 | qs: { 90 | expand: expand 91 | } 92 | }; 93 | 94 | return this.jiraClient.makeRequest(options, callback); 95 | }; 96 | 97 | /** 98 | * Updates a permission scheme. 99 | * 100 | * If the permissions list is present then it will be set in the permission scheme, 101 | * which basically means it will overwrite any permission grants that existed in the permission scheme. 102 | * Sending an empty list will remove all permission grants from the permission scheme. 103 | * 104 | * To update just the name and description, do not send permissions list at all. 105 | * To add or remove a single permission grant instead of updating the whole list 106 | * at once use the {schemeId}/permission/ resource. 107 | * 108 | * @method editPermissionScheme 109 | * @memberOf PermissionSchemeClient# 110 | * @param opts The request options sent to the Jira API 111 | * @param opts.schemeId The id of the scheme to retrieve. 112 | * @param opts.scheme The body of the scheme to edit. 113 | * @param [callback] Called when the user has been edited. 114 | * @return {Promise} Resolved when the user has been edited. 115 | */ 116 | this.editPermissionScheme = function (opts, callback) { 117 | var options = { 118 | uri: this.jiraClient.buildURL('/permissionscheme/' + opts.schemeId), 119 | method: 'PUT', 120 | json: true, 121 | followAllRedirects: true, 122 | body: opts.scheme 123 | }; 124 | 125 | return this.jiraClient.makeRequest(options, callback); 126 | }; 127 | 128 | /** 129 | * Removes Permission Scheme. 130 | * 131 | * @method deletePermissionScheme 132 | * @memberOf PermissionSchemeClient# 133 | * @param opts The request options sent to the Jira API 134 | * @param opts.schemeId The name of the scheme to delete. 135 | * @param [callback] Called when the scheme has been deleted. 136 | * @return {Promise} Resolved when the scheme has been deleted. 137 | */ 138 | this.deletePermissionScheme = function (opts, callback) { 139 | var options = { 140 | uri: this.jiraClient.buildURL('/permissionscheme/' + opts.schemeId), 141 | method: 'DELETE', 142 | json: true, 143 | followAllRedirects: true 144 | }; 145 | 146 | return this.jiraClient.makeRequest(options, callback, 'Permission Scheme removed.'); 147 | }; 148 | 149 | /** 150 | * Returns all permission grants of the given permission scheme. 151 | * 152 | * @method getPermissionSchemeGrants 153 | * @memberOf PermissionSchemeClient# 154 | * @param opts The request options sent to the Jira API 155 | * @param opts.schemeId The id of the scheme to which the permission grant belongs. 156 | * @param {Object} opts.expand The fields to be expanded. 157 | * @param [callback] Called when the scheme grants have been retrieved. 158 | * @return {Promise} Resolved when the scheme grants have been retrieved. 159 | */ 160 | this.getPermissionSchemeGrants = function (opts, callback) { 161 | var expand = opts.expand 162 | if (opts.expand && opts.expand instanceof Array) { 163 | expand = opts.expand.join(','); 164 | } 165 | var options = { 166 | uri: this.jiraClient.buildURL('/permissionscheme/' + opts.schemeId + '/permission'), 167 | method: 'GET', 168 | json: true, 169 | followAllRedirects: true, 170 | qs: { 171 | expand: expand 172 | } 173 | }; 174 | 175 | return this.jiraClient.makeRequest(options, callback); 176 | }; 177 | 178 | /** 179 | * Creates a permission grant in a permission scheme. 180 | * 181 | * @method createPermissionGrantInScheme 182 | * @memberOf PermissionSchemeClient# 183 | * @param opts The request options sent to the Jira API. 184 | * @param opts.schemeId The id of the scheme to which the permission grant belongs. 185 | * @param opts.grant See {@link https://docs.atlassian.com/software/jira/docs/api/REST/7.6.1/#api/2/permissionscheme-createPermissionGrant} 186 | * @param [callback] Called when the permission grant has been created. 187 | * @return {Promise} Resolved when the permission grant has been created. 188 | */ 189 | this.createPermissionGrantInScheme = function (opts, callback) { 190 | var options = { 191 | uri: this.jiraClient.buildURL('/permissionscheme/' + opts.schemeId + '/permission'), 192 | method: 'POST', 193 | json: true, 194 | followAllRedirects: true, 195 | body: opts.grant 196 | }; 197 | 198 | return this.jiraClient.makeRequest(options, callback); 199 | } 200 | 201 | /** 202 | * Deletes a permission grant from a permission scheme. 203 | * 204 | * @method deletePermissionGrantFromScheme 205 | * @memberOf PermissionSchemeClient# 206 | * @param opts The request options sent to the Jira API 207 | * @param opts.schemeId The name of the scheme to delete. 208 | * @param opts.permissionId The id of the permission to delete. 209 | * @param [callback] Called when the scheme has been deleted. 210 | * @return {Promise} Resolved when the scheme has been deleted. 211 | */ 212 | this.deletePermissionGrantFromScheme = function (opts, callback) { 213 | var options = { 214 | uri: this.jiraClient.buildURL('/permissionscheme/' + opts.schemeId + '/permission/' + opts.permissionId), 215 | method: 'DELETE', 216 | json: true, 217 | followAllRedirects: true 218 | }; 219 | 220 | return this.jiraClient.makeRequest(options, callback, 'Permission removed from scheme.'); 221 | }; 222 | 223 | /** 224 | * Returns a permission grant identified by the given id. 225 | * 226 | * @method getPermissionSchemeGrantById 227 | * @memberOf PermissionSchemeClient# 228 | * @param opts The request options sent to the Jira API 229 | * @param opts.schemeId The id of the scheme to which the permission grant belongs. 230 | * @param opts.permissionId The id of the permission to fetch. 231 | * @param {Object} opts.expand The fields to be expanded. 232 | * @param [callback] Called when the scheme grants have been retrieved. 233 | * @return {Promise} Resolved when the scheme grants have been retrieved. 234 | */ 235 | this.getPermissionSchemeGrantById = function (opts, callback) { 236 | var expand = opts.expand 237 | if (opts.expand && opts.expand instanceof Array) { 238 | expand = opts.expand.join(','); 239 | } 240 | var options = { 241 | uri: this.jiraClient.buildURL('/permissionscheme/' + opts.schemeId + '/permission/' + opts.permissionId), 242 | method: 'GET', 243 | json: true, 244 | followAllRedirects: true, 245 | qs: { 246 | expand: expand 247 | } 248 | }; 249 | 250 | return this.jiraClient.makeRequest(options, callback); 251 | }; 252 | } -------------------------------------------------------------------------------- /api/epic.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | 3 | module.exports = AgileEpicClient; 4 | 5 | /** 6 | * Used to access Jira REST endpoints in '/rest/agile/1.0/epic' 7 | * @param {JiraClient} jiraClient 8 | * @constructor AgileEpicClient 9 | */ 10 | function AgileEpicClient(jiraClient) { 11 | this.jiraClient = jiraClient; 12 | 13 | /** 14 | * Returns all issues that do not belong to any epic. This only includes issues that 15 | * the user has permission to view. Issues returned from this resource include Agile fields, 16 | * like sprint, closedSprints, flagged, and epic. By default, the returned issues are ordered by rank. 17 | * 18 | * @method getIssuesWithoutEpic 19 | * @memberOf AgileEpicClient 20 | * @param { Object } [opts] The request options to send to the Jira API 21 | * @param { number } [opts.startAt] The index of the first dashboard to return (0-based). must be 0 or a multiple of 22 | * maxResults 23 | * @param { number } [opts.maxResults] A hint as to the the maximum number of dashboards to return in each call. Note that the 24 | * JIRA server reserves the right to impose a maxResults limit that is lower than the value that a client 25 | * provides, dues to lack or resources or any other condition. When this happens, your results will be 26 | * truncated. Callers should always check the returned maxResults to determine the value that is effectively 27 | * being used. 28 | * @param { string } [opts.jql] 29 | * @param { boolean } [opts.validateQuery] 30 | * @param { Array } [opts.fields] 31 | * @param { string } [opts.expand] 32 | * @param { Function } [callback] Called when the dashboards have been retrieved. 33 | * @return { Promise } Resolved when the dashboards have been retrieved. 34 | */ 35 | this.getIssuesWithoutEpic = function (opts, callback) { 36 | var endpoint = this.jiraClient.buildAgileURL('/epic/none/issue'); 37 | opts = opts || {}; 38 | 39 | var options = { 40 | uri: endpoint, 41 | method: 'GET', 42 | json: true, 43 | followAllRedirects: true, 44 | qs: { 45 | startAt: opts.startAt, 46 | maxResults: opts.maxResults, 47 | jql: opts.jql, 48 | validateQuery: opts.validateQuery, 49 | fields: opts.fields ? opts.fields.join(',') : undefined, 50 | expand: opts.expand 51 | } 52 | }; 53 | 54 | return this.jiraClient.makeRequest(options, callback); 55 | } 56 | 57 | /** 58 | * Removes issues from epics. 59 | * The user needs to have the edit issue permission for all issue they want to remove from epics. 60 | * The maximum number of issues that can be moved in one operation is 50. 61 | * 62 | * @method removeIssuesFromEpic 63 | * @memberOf AgileEpicClient 64 | * @param opts The request options to send to the Jira API 65 | * @param { string[] } [opts.issues] 66 | * @param { Function } [callback] Called when the dashboards have been retrieved. 67 | * @return { Promise } Resolved when the dashboards have been retrieved. 68 | */ 69 | this.removeIssuesFromEpic = function (opts, callback) { 70 | var endpoint = this.jiraClient.buildAgileURL('/epic/none/issue'); 71 | opts = opts || {}; 72 | 73 | var options = { 74 | uri: endpoint, 75 | method: 'POST', 76 | json: true, 77 | followAllRedirects: true, 78 | body: { 79 | issues: opts.issues 80 | } 81 | }; 82 | 83 | return this.jiraClient.makeRequest(options, callback); 84 | } 85 | 86 | /** 87 | * Returns the epic for a given epic ID. This epic will only be returned if the user has permission to view it. 88 | * 89 | * @method getEpic 90 | * @memberOf AgileEpicClient 91 | * @param opts The request options to send to the Jira API 92 | * @param { number | string } opts.epicId 93 | * @param { Function } [callback] Called when the dashboards have been retrieved. 94 | * @return { Promise } Resolved when the dashboards have been retrieved. 95 | */ 96 | this.getEpic = function (opts, callback) { 97 | var endpoint = this.jiraClient.buildAgileURL('/epic/' + opts.epicId); 98 | 99 | var options = { 100 | uri: endpoint, 101 | method: 'GET', 102 | json: true, 103 | followAllRedirects: true 104 | }; 105 | 106 | return this.jiraClient.makeRequest(options, callback); 107 | } 108 | 109 | /** 110 | * Performs a partial update of the epic. A partial update means that fields not present 111 | * in the request JSON will not be updated. Valid values for color are color_1 to color_9. 112 | * 113 | * @method partiallyUpdateEpic 114 | * @memberOf AgileEpicClient 115 | * @param opts The request options to send to the Jira API 116 | * @param { number | string } opts.epicId 117 | * @param { string } [opts.name] 118 | * @param { string } [opts.summary] 119 | * @param { any } [opts.color] 120 | * @param { boolean } [opts.done] 121 | * @param { Function } [callback] Called when the dashboards have been retrieved. 122 | * @return { Promise } Resolved when the dashboards have been retrieved. 123 | */ 124 | this.partiallyUpdateEpic = function (opts, callback) { 125 | var endpoint = this.jiraClient.buildAgileURL('/epic/' + opts.epicId); 126 | 127 | var options = { 128 | uri: endpoint, 129 | method: 'POST', 130 | json: true, 131 | followAllRedirects: true, 132 | body: { 133 | name: opts.name, 134 | summary: opts.summary, 135 | color: opts.color, 136 | done: opts.done 137 | } 138 | }; 139 | 140 | return this.jiraClient.makeRequest(options, callback); 141 | } 142 | 143 | /** 144 | * Get a list of all issues associated with an agile epic 145 | * 146 | * @method getIssuesForEpic 147 | * @memberOf AgileEpicClient 148 | * @param opts The request options to send to the Jira API 149 | * @param { string | number } opts.epicId epic id or epic key 150 | * @param { number } [opts.startAt] The index of the first dashboard to return (0-based). must be 0 or a multiple of 151 | * maxResults 152 | * @param { number } [opts.maxResults] A hint as to the the maximum number of dashboards to return in each call. Note that the 153 | * JIRA server reserves the right to impose a maxResults limit that is lower than the value that a client 154 | * provides, dues to lack or resources or any other condition. When this happens, your results will be 155 | * truncated. Callers should always check the returned maxResults to determine the value that is effectively 156 | * being used. 157 | * @param { string } [opts.jql] 158 | * @param { boolean } [opts.validateQuery] 159 | * @param { Array } [opts.fields] 160 | * @param { string } [opts.expand] 161 | * @param { Function } [callback] Called when the dashboards have been retrieved. 162 | * @return { Promise } Resolved when the dashboards have been retrieved. 163 | */ 164 | this.getIssuesForEpic = function (opts, callback) { 165 | var options = { 166 | uri: this.jiraClient.buildAgileURL('/epic/' + opts.epicId + '/issue'), 167 | method: 'GET', 168 | json: true, 169 | followAllRedirects: true, 170 | qs: { 171 | startAt: opts.startAt, 172 | maxResults: opts.maxResults, 173 | jql: opts.jql, 174 | validateQuery: opts.validateQuery, 175 | fields: opts.fields ? opts.fields.join(',') : undefined, 176 | expand: opts.expand 177 | } 178 | }; 179 | 180 | return this.jiraClient.makeRequest(options, callback); 181 | }; 182 | 183 | /** 184 | * Moves issues to an epic, for a given epic id. Issues can be only in a single epic at the same time. 185 | * That means that already assigned issues to an epic, will not be assigned to the previous epic anymore. 186 | * The user needs to have the edit issue permission for all issue they want to move and to the epic. 187 | * The maximum number of issues that can be moved in one operation is 50. 188 | * 189 | * @method moveIssuesToEpic 190 | * @memberOf AgileEpicClient 191 | * @param opts The request options to send to the Jira API 192 | * @param { number | string } opts.epicId 193 | * @param { string[] } [opts.issues] 194 | * @param { Function } [callback] Called when the dashboards have been retrieved. 195 | * @return { Promise } Resolved when the dashboards have been retrieved. 196 | */ 197 | this.moveIssuesToEpic = function (opts, callback) { 198 | var endpoint = this.jiraClient.buildAgileURL('/epic/' + opts.epicId + '/issue'); 199 | 200 | var options = { 201 | uri: endpoint, 202 | method: 'POST', 203 | json: true, 204 | followAllRedirects: true, 205 | body: { 206 | issues: opts.issues 207 | } 208 | }; 209 | 210 | return this.jiraClient.makeRequest(options, callback); 211 | } 212 | 213 | /** 214 | * Moves (ranks) an epic before or after a given epic. 215 | * 216 | * If rankCustomFieldId is not defined, the default rank field will be used. 217 | * 218 | * @method rankEpics 219 | * @memberOf AgileEpicClient 220 | * @param opts The request options to send to the Jira API 221 | * @param { number | string } opts.epicId 222 | * @param { string } [opts.rankBeforeEpic] 223 | * @param { string } [opts.rankAfterEpic] 224 | * @param { number } [opts.rankCustomFieldId] 225 | * @param { Function } [callback] Called when the dashboards have been retrieved. 226 | * @return { Promise } Resolved when the dashboards have been retrieved. 227 | */ 228 | this.rankEpics = function (opts, callback) { 229 | var endpoint = this.jiraClient.buildAgileURL('/epic/' + opts.epicId + '/rank'); 230 | 231 | var options = { 232 | uri: endpoint, 233 | method: 'PUT', 234 | json: true, 235 | followAllRedirects: true, 236 | body: { 237 | rankBeforeEpic: opts.rankBeforeEpic, 238 | rankAfterEpic: opts.rankAfterEpic, 239 | rankCustomFieldId: opts.rankCustomFieldId 240 | } 241 | }; 242 | 243 | return this.jiraClient.makeRequest(options, callback); 244 | } 245 | } 246 | -------------------------------------------------------------------------------- /api/screens.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | 3 | module.exports = ScreensClient; 4 | 5 | /** 6 | * Used to access Jira REST endpoints in '/rest/api/2/screens' 7 | * 8 | * @param {JiraClient} jiraClient 9 | * @constructor ScreensClient 10 | */ 11 | function ScreensClient(jiraClient) { 12 | this.jiraClient = jiraClient; 13 | 14 | /** 15 | * Gets available fields for screen. i.e ones that haven't already been added. 16 | * 17 | * @method getAvailableFields 18 | * @memberOf ScreensClient# 19 | * @param {Object} opts The request options sent to Jira 20 | * @param {number} opts.screenId The id of the screen to retrieve. 21 | * @param [callback] Called when the available fields have been retrieved 22 | * @return {Promise} Resolved when the available fields have been retrieved 23 | */ 24 | this.getAvailableFields = function (opts, callback) { 25 | var options = this.buildRequestOptions(opts, '/availableFields', 'GET'); 26 | return this.jiraClient.makeRequest(options, callback); 27 | }; 28 | 29 | /** 30 | * Returns a list of all tabs for the given screen. 31 | * 32 | * @method getTabs 33 | * @memberOf ScreensClient# 34 | * @param {Object} opts The request options sent to Jira 35 | * @param {number} opts.screenId The id of the screen to retrieve. 36 | * @param [callback] Called when the tabs have been retrieved. 37 | * @return {Promise} Resolved when the tabs have been retrieved. 38 | */ 39 | this.getTabs = function (opts, callback) { 40 | var options = this.buildRequestOptions(opts, '/tabs', 'GET'); 41 | return this.jiraClient.makeRequest(options, callback); 42 | }; 43 | 44 | /** 45 | * Creates tab for given screen 46 | * 47 | * @method createTab 48 | * @memberOf ScreensClient# 49 | * @param {Object} opts The request options sent to Jira 50 | * @param {number} opts.screenId The id of the screen in which to create a tab. 51 | * @param {string} opts.name The name of the tab to add. Minimum required to create a tab. 52 | * @param [callback] Called when the tab has been created. 53 | * @return {Promise} Resolved when the tab has been created. 54 | */ 55 | this.createTab = function (opts, callback) { 56 | var options = this.buildRequestOptions(opts, '/tabs', 'POST', {name: opts.name}); 57 | return this.jiraClient.makeRequest(options, callback); 58 | }; 59 | 60 | /** 61 | * Renames the given tab on the given screen. 62 | * 63 | * @method renameTab 64 | * @memberOf ScreensClient# 65 | * @param {Object} opts The request options sent to the jira API 66 | * @param {number} opts.screenId The id of the screen containing the tab to rename. 67 | * @param {number} opts.tabId The id of the tab to rename 68 | * @param {string} opts.name The new name of the tab. 69 | * @param [callback] Called when data has been retrieved 70 | * @return {Promise} Resolved when data has been retrieved 71 | */ 72 | this.renameTab = function (opts, callback) { 73 | var options = this.buildRequestOptions(opts, '/tabs/' + opts.tabId, 'PUT', {name: opts.name}); 74 | return this.jiraClient.makeRequest(options, callback); 75 | }; 76 | 77 | /** 78 | * Deletes the given tab from the given screen. 79 | * 80 | * @method deleteTab 81 | * @memberOf ScreensClient# 82 | * @param {Object} opts The request options sent to the jira API 83 | * @param {number} opts.screenId The id of the screen containing the tab to delete. 84 | * @param {number} opts.tabId The id of the tab to delete 85 | * @param [callback] Called when data has been retrieved 86 | * @return {Promise} Resolved when data has been retrieved 87 | */ 88 | this.deleteTab = function (opts, callback) { 89 | var options = this.buildRequestOptions(opts, '/tabs/' + opts.tabId, 'DELETE'); 90 | return this.jiraClient.makeRequest(options, callback, 'Tab Deleted'); 91 | }; 92 | 93 | /** 94 | * Adds field to the given tab 95 | * 96 | * @method addFieldToTab 97 | * @memberOf ScreensClient# 98 | * @param {Object} opts The request options sent to the Jira API 99 | * @param {number} opts.screenId The id of the screen containing the tab. 100 | * @param {number} opts.tabId the id of the tab to which the fields will be added. 101 | * @param {string} opts.fieldId The field to add 102 | * @param [callback] Called when the fields have been added to the tab. 103 | * @return {Promise} Resolved when the fields have been added to the tab. 104 | */ 105 | this.addFieldToTab = function (opts, callback) { 106 | var options = this.buildRequestOptions(opts, '/tabs/' + opts.tabId + '/fields', 'POST', opts.fieldId); 107 | return this.jiraClient.makeRequest(options, callback); 108 | }; 109 | 110 | /** 111 | * Gets all fields for a given tab. 112 | * 113 | * @method getFieldsInTab 114 | * @memberOf ScreensClient# 115 | * @param {Object} opts The request options sent to the Jira API 116 | * @param {number} opts.screenId The id of the screen containing the tab. 117 | * @param {number} opts.tabId the id of the tab for which to retrieve fields. 118 | * @param [callback] Called when the fields have been retrieved. 119 | * @return {Promise} Resolved when the fields have been retrieved. 120 | */ 121 | this.getFieldsInTab = function (opts, callback) { 122 | var options = this.buildRequestOptions(opts, '/tabs/' + opts.tabId + '/fields', 'GET'); 123 | return this.jiraClient.makeRequest(options, callback); 124 | }; 125 | 126 | /** 127 | * Remove the given field from the given tab. 128 | * 129 | * @method removeFieldFromTab 130 | * @memberOf ScreensClient# 131 | * @param {Object} opts The request options sent to the Jira API 132 | * @param {number} opts.screenId The id of the screen containing the tab. 133 | * @param {number} opts.tabId the id of the tab from which to remove the field. 134 | * @param {string} opts.fieldId The id of the field to remove from the tab. 135 | * @param [callback] Called when the field has been removed. 136 | * @return {Promise} Resolved when the field has been removed. 137 | */ 138 | this.removeFieldFromTab = function (opts, callback) { 139 | var options = this.buildRequestOptions(opts, '/tabs/' + opts.tabId + '/fields/' + opts.fieldId, 'DELETE'); 140 | return this.jiraClient.makeRequest(options, callback, 'Field Removed From Tab'); 141 | }; 142 | 143 | /** 144 | * Move the given field on the given tab 145 | * 146 | * @method moveFieldOnTab 147 | * @memberOf ScreensClient# 148 | * @param {Object} opts The request options sent to the Jira API 149 | * @param {number} opts.screenId The id of the screen containing the tab. 150 | * @param {number} opts.tabId the id of the tab containing the field. 151 | * @param {string} opts.fieldId The id of the field to remove from the tab. 152 | * @param {number} opts.newPosition The position to which the field should be moved. May be one of: 153 | * * Earlier 154 | * * Later 155 | * * First 156 | * * Last 157 | * @param [callback] Called when the field has been removed. 158 | * @return {Promise} Resolved when the field has been removed. 159 | */ 160 | this.moveFieldOnTab = function (opts, callback) { 161 | var options = this.buildRequestOptions(opts, '/tabs/' + opts.tabId + '/fields/' + opts.fieldId + '/move', 162 | 'POST', {position: opts.newPosition}); 163 | return this.jiraClient.makeRequest(options, callback, 'Field Moved'); 164 | }; 165 | 166 | /** 167 | * Moves tab position 168 | * 169 | * @method moveTabPosition 170 | * @memberOf ScreensClient# 171 | * @param {Object} opts The request options sent to the Jira API. 172 | * @param {number} opts.screenId The id of the screen containing the tab. 173 | * @param {number} opts.tabId the id of the tab to move. 174 | * @param {number} opts.newPosition The new (zero-indexed) position of the tab. 175 | * @param [callback] Called when the tab has been moved. 176 | * @return {Promise} Resolved when the tab has been moved. 177 | */ 178 | this.moveTabPosition = function (opts, callback) { 179 | var options = this.buildRequestOptions(opts, '/tabs/' + opts.tabId + '/move/' + opts.newPosition, 'POST'); 180 | return this.jiraClient.makeRequest(options, callback, 'Tab Moved'); 181 | }; 182 | 183 | /** 184 | * Adds field or custom field to the default tab 185 | * 186 | * @method addFieldToDefaultTab 187 | * @memberOf ScreensClient# 188 | * @param {Object} opts The request options sent to the Jira API. 189 | * @param {string} opts.fieldId The id of the field to add to the default tab. 190 | * @param [callback] Called when the tab has been moved. 191 | * @return {Promise} Resolved when the tab has been moved. 192 | */ 193 | this.addFieldToDefaultTab = function (opts, callback) { 194 | var options = { 195 | uri: this.jiraClient.buildURL('/screens/addToDefault/' + opts.fieldId), 196 | method: 'POST', 197 | json: true, 198 | followAllRedirects: true 199 | }; 200 | 201 | return this.jiraClient.makeRequest(options, callback); 202 | }; 203 | 204 | /** 205 | * Build out the request options necessary to make a particular API call. 206 | * 207 | * @private 208 | * @method buildRequestOptions 209 | * @memberOf FilterClient# 210 | * @param {Object} opts The arguments passed to the method. 211 | * @param {number} opts.screenId The id of the screen to use in the path. 212 | * @param {Array} [opts.fields] The fields to include 213 | * @param {Array} [opts.expand] The fields to expand 214 | * @param {string} path The path of the endpoint following /screen/{id} 215 | * @param {string} method The request method. 216 | * @param {Object} [body] The request body, if any. 217 | * @param {Object} [qs] The querystring, if any. opts.expand and opts.fields arrays will be automagically added. 218 | * @returns {{uri: string, method: string, body: Object, qs: Object, followAllRedirects: boolean, json: boolean}} 219 | */ 220 | this.buildRequestOptions = function (opts, path, method, body, qs) { 221 | var basePath = '/screens/' + opts.screenId; 222 | if (!qs) qs = {}; 223 | if (!body) body = {}; 224 | 225 | if (opts.fields) { 226 | qs.fields = ''; 227 | opts.fields.forEach(function (field) { 228 | qs.fields += field + ',' 229 | }); 230 | qs.fields = qs.fields.slice(0, -1); 231 | } 232 | 233 | if (opts.expand) { 234 | qs.expand = ''; 235 | opts.expand.forEach(function (ex) { 236 | qs.expand += ex + ',' 237 | }); 238 | qs.expand = qs.expand.slice(0, -1); 239 | } 240 | 241 | return { 242 | uri: this.jiraClient.buildURL(basePath + path), 243 | method: method, 244 | body: body, 245 | qs: qs, 246 | followAllRedirects: true, 247 | json: true 248 | }; 249 | }; 250 | } --------------------------------------------------------------------------------