UNPKG

axios-redmine

Version:

axios-redmine is a nodejs library which supports 100% features of Redmine's REST API.

714 lines (630 loc) 21.2 kB
/*! * axios-redmine * A nodejs library which supports 100% features of Redmine's REST API. * Author: lupinthe14th <hideosuzuki@ordinarius-fectum.net> * Reference: http://www.redmine.org/projects/redmine/wiki/Rest_api */ 'use strict()' /** * Module dependencies */ const axios = require('axios') const url = require('url') const https = require('https') /** * Redmine * * @param {String} host, Redmine hostname * @param {Object} config * - {String} apiKey, API access key for Redmine, if apiKey occured, username and password will be ignored. * - {String} username, username to login Redmine. * - {String} password, password for login Redmine. * - {String} impersonate, impersonate to a login user. * - {Boolean} rejectUnauthorized, If not false a server automatically reject clients with invalid certificates. * @param {String} port, Redmine port (defaults to 80) */ function Redmine(host, config, port) { try { if (!host) throw new Error('host not specified!') if (typeof host === 'string') { host = new URL(host) } else if (typeof host !== 'object') { throw new Error('host should be a string or url object!') } if (port) { host.port = port host.host += `:${port.toString()}` } const baseUrl = url.format(host) this.instance = axios.create({ baseURL: baseUrl }) if (!config || !(config.apiKey || (config.username && config.password))) { throw new Error('You should provide an API key or username & password !') } } catch (e) { return e } this.config = config } Redmine.prototype = { // get & set property get apiKey() { return this.config.apiKey }, set apiKey(apiKey) { this.config.apiKey = apiKey }, get username() { return this.config.username }, set username(username) { this.config.username = username }, get password() { return this.config.password }, set password(password) { this.config.password = password }, get impersonate() { return this.config.impersonate }, set impersonate(impersonateId) { this.config.impersonate = impersonateId }, get rejectUnauthorized() { return this.config.rejectUnauthorized === '1' }, set rejectUnauthorized(rejectUnauthorized) { this.config.rejectUnauthorized = rejectUnauthorized } } /** * request - request url from Redmine */ Redmine.prototype.request = function(method, path, params) { const isUpload = path === '/uploads.json' const opts = { method, params: method === 'GET' ? params : undefined, data: ['PATCH', 'POST', 'PUT'].includes(method) ? params : undefined, headers: { 'Content-Type': !isUpload ? 'application/json' : 'application/octet-stream' }, // auth: { user: this.username, pass: this.password }, responseType: 'json' } // tls rejectUnauthorized if (this.rejectUnauthorized) { const agent = new https.Agent({ rejectUnauthorized: false }) opts.httpsAgent = agent } // impersonate to a login user if (this.impersonate) { opts.headers['X-Redmine-Switch-User'] = this.impersonate } if (this.apiKey) { opts.headers['X-Redmine-API-Key'] = this.config.apiKey } else if (this.username && this.password) { opts.auth = { username: this.username, password: this.password } } else { throw new Error('Neither api key nor username/password provided !') } return this.instance(path, opts) } // REST API for issues (Stable) /** * Listing issues * Returns a paginated list of issues. By default, it returns open issues only. * http://www.redmine.org/projects/redmine/wiki/Rest_Issues#Listing-issues */ Redmine.prototype.issues = function(params) { return this.request('GET', '/issues.json', params) } /** * Showing an issue * http://www.redmine.org/projects/redmine/wiki/Rest_Issues#Showing-an-issue */ Redmine.prototype.get_issue_by_id = function(id, params) { if (typeof id !== 'number') { throw new Error('Issue ID must be an integer above ' + id + ' !') } return this.request('GET', `/issues/${id}.json`, params) } /** * Creating an issue * http://www.redmine.org/projects/redmine/wiki/Rest_Issues#Creating-an-issue */ Redmine.prototype.create_issue = function(issue) { return this.request('POST', '/issues.json', issue) } /** * Updating an issue * http://www.redmine.org/projects/redmine/wiki/Rest_Issues#Updating-an-issue */ Redmine.prototype.update_issue = function(id, issue) { return this.request('PUT', `/issues/${id}.json`, issue) } /** * Deleting an issue * http://www.redmine.org/projects/redmine/wiki/Rest_Issues#Deleting-an-issue */ Redmine.prototype.delete_issue = function(id) { return this.request('DELETE', `/issues/${id}.json`, {}) } /** * Adding a watcher * http://www.redmine.org/projects/redmine/wiki/Rest_Issues#Adding-a-watcher */ Redmine.prototype.add_watcher = function(id, params) { if (!params.user_id) { throw new Error('user_id (required): id of the user to add as a watcher !') } return this.request('POST', `/issues/${id}/watchers.json`, params) } /** * Removing a watcher * http://www.redmine.org/projects/redmine/wiki/Rest_Issues#Removing-a-watcher */ Redmine.prototype.remove_watcher = function(issueId, userId) { return this.request( 'DELETE', `/issues/${issueId}/watchers/${userId}.json`, {} ) } // REST API for Projects (Stable) /** * Listing projects * http://www.redmine.org/projects/redmine/wiki/Rest_Projects#Listing-projects */ Redmine.prototype.projects = function(params) { return this.request('GET', '/projects.json', params) } /** * Showing a project * http://www.redmine.org/projects/redmine/wiki/Rest_Projects#Showing-a-project */ Redmine.prototype.get_project_by_id = function(id, params) { return this.request('GET', `/projects/${id}.json`, params) } /** * Creating a project * http://www.redmine.org/projects/redmine/wiki/Rest_Projects#Creating-a-project */ Redmine.prototype.create_project = function(params) { return this.request('POST', '/projects.json', params) } /** * Updating a project - Updates the project of given id or identifier * http://www.redmine.org/projects/redmine/wiki/Rest_Projects#Updating-a-project */ Redmine.prototype.update_project = function(id, params) { return this.request('PUT', `/projects/${id}.json`, params) } /** * Deleting a project - Deletes the project of given id or identifier * http://www.redmine.org/projects/redmine/wiki/Rest_Projects#Deleting-a-project */ Redmine.prototype.delete_project = function(id) { return this.request('DELETE', `/projects/${id}.json`, {}) } // REST API for Users (Stable) /** * list Users * http://www.redmine.org/projects/redmine/wiki/Rest_Users#GET */ Redmine.prototype.users = function(params) { return this.request('GET', '/users.json', params) } /** * Returns the user details * http://www.redmine.org/projects/redmine/wiki/Rest_Users#GET-2 */ Redmine.prototype.get_user_by_id = function(id, params) { return this.request('GET', `/users/${id}.json`, params) } /** * Returns current user details * http://www.redmine.org/projects/redmine/wiki/Rest_Users#GET-2 */ Redmine.prototype.current_user = function(params) { return this.request('GET', '/users/current.json', params) } /** * create user * http://www.redmine.org/projects/redmine/wiki/Rest_Users#POST */ Redmine.prototype.create_user = function(params) { return this.request('POST', '/users.json', params) } /** * update user * http://www.redmine.org/projects/redmine/wiki/Rest_Users#PUT */ Redmine.prototype.update_user = function(id, params) { return this.request('PUT', `/users/${id}.json`, params) } /** * Deleting user * http://www.redmine.org/projects/redmine/wiki/Rest_Users#DELETE */ Redmine.prototype.delete_user = function(id) { return this.request('DELETE', `/users/${id}.json`, {}) } // REST API for Time Entries (Stable) /** * Listing time entries * http://www.redmine.org/projects/redmine/wiki/Rest_TimeEntries#Listing-time-entries */ Redmine.prototype.time_entries = function(params) { return this.request('GET', '/time_entries.json', params) } /** * Showing a time entry * http://www.redmine.org/projects/redmine/wiki/Rest_TimeEntries#Showing-a-time-entry */ Redmine.prototype.get_time_entry_by_id = function(id) { return this.request('GET', `/time_entries/${id}.json`, {}) } /** * Creating a time entry * http://www.redmine.org/projects/redmine/wiki/Rest_TimeEntries#Creating-a-time-entry */ Redmine.prototype.create_time_entry = function(params) { return this.request('POST', '/time_entries.json', params) } /** * Updating a time entry * http://www.redmine.org/projects/redmine/wiki/Rest_TimeEntries#Updating-a-time-entry */ Redmine.prototype.update_time_entry = function(id, params) { return this.request('PUT', `/time_entries/${id}.json`, params) } /** * Deleting a time entry * http://www.redmine.org/projects/redmine/wiki/Rest_TimeEntries#Deleting-a-time-entry */ Redmine.prototype.delete_time_entry = function(id) { return this.request('DELETE', `/time_entries/${id}.json`, {}) } // REST API for Project Memberships (Alpha) /** * Returns a paginated list of the project memberships. :project_id can be either the project numerical id or the project identifier. * http://www.redmine.org/projects/redmine/wiki/Rest_Memberships#GET */ Redmine.prototype.membership_by_project_id = function(id, params) { return this.request('GET', `/projects/${id}/memberships.json`, params) } /** * Adds a project member * http://www.redmine.org/projects/redmine/wiki/Rest_Memberships#POST */ Redmine.prototype.create_project_membership = function(id, params) { return this.request('POST', `/projects/${id}/memberships.json`, params) } /** * Returns the membership of given :id. * http://www.redmine.org/projects/redmine/wiki/Rest_Memberships#GET-2 */ Redmine.prototype.project_membership_by_id = function(id, params) { return this.request('GET', `/memberships/${id}.json`, params) } /** * Updates the membership of given :id. Only the roles can be updated, the project and the user of a membership are read-only. * http://www.redmine.org/projects/redmine/wiki/Rest_Memberships#PUT */ Redmine.prototype.update_project_membership = function(id, params) { return this.request('PUT', `/memberships/${id}.json`, params) } /** * Deletes a memberships * http://www.redmine.org/projects/redmine/wiki/Rest_Memberships#DELETE */ Redmine.prototype.delete_project_membership = function(id) { return this.request('DELETE', `/memberships/${id}.json`, {}) } // REST API for Issue Relations (Alpha) /** * Returns the relations for the issue of given id (:issue_id). * http://www.redmine.org/projects/redmine/wiki/Rest_IssueRelations#GET */ Redmine.prototype.issue_relation_by_issue_id = function(id) { return this.request('GET', `/issues/${id}/relations.json`, {}) } /** * Creates a relation for the issue of given id (:issue_id). * http://www.redmine.org/projects/redmine/wiki/Rest_IssueRelations#POST */ Redmine.prototype.create_issue_relation = function(id, params) { return this.request('POST', `/issues/${id}/relations.json`, params) } /** * Returns the relation of given id. * http://www.redmine.org/projects/redmine/wiki/Rest_IssueRelations#GET-2 */ Redmine.prototype.issue_relation_by_id = function(id) { return this.request('GET', `/relations/${id}.json`, {}) } /** * Deletes the relation of given id. * http://www.redmine.org/projects/redmine/wiki/Rest_IssueRelations#DELETE */ Redmine.prototype.delete_issue_relation = function(id) { return this.request('DELETE', `/relations/${id}.json`, {}) } // REST API for News (Prototype) /** * Returns all news across all projects with pagination * http://www.redmine.org/projects/redmine/wiki/Rest_News#GET */ Redmine.prototype.news = function(params) { return this.request('GET', '/news.json', params) } /** * Returns all news from project with given id or identifier with pagination. * http://www.redmine.org/projects/redmine/wiki/Rest_News#GET-2 */ Redmine.prototype.new_by_project_id = function(id) { return this.request('GET', `/projects/${id}/news.json`, {}) } // REST API for Versions (Alpha) /** * Returns the versions available for the project of given id or identifier (:project_id). * The response may include shared versions from other projects. * http://www.redmine.org/projects/redmine/wiki/Rest_Versions#GET */ Redmine.prototype.version_by_project_id = function(id) { return this.request('GET', `/projects/${id}/versions.json`, {}) } /** * Creates a version for the project of given id or identifier (:project_id). * http://www.redmine.org/projects/redmine/wiki/Rest_Versions#POST */ Redmine.prototype.create_version = function(id, params) { return this.request('POST', `/projects/${id}/versions.json`, params) } /** * Returns the version of given id * http://www.redmine.org/projects/redmine/wiki/Rest_Versions#GET-2 */ Redmine.prototype.version_by_id = function(id) { return this.request('GET', `/versions/${id}.json`, {}) } /** * Updates the version of given id * http://www.redmine.org/projects/redmine/wiki/Rest_Versions#PUT */ Redmine.prototype.update_version = function(id, params) { return this.request('PUT', `/versions/${id}.json`, params) } /** * Deletes the version of given id * http://www.redmine.org/projects/redmine/wiki/Rest_Versions#DELETE */ Redmine.prototype.delete_version = function(id) { return this.request('DELETE', `/versions/${id}.json`, {}) } // REST API for Wiki Pages (Alpha) /** * Getting the pages list of a wiki * http://www.redmine.org/projects/redmine/wiki/Rest_WikiPages#Wiki-Pages */ Redmine.prototype.wiki_by_project_id = function(id) { return this.request('GET', `/projects/${id}/wiki/index.json`, {}) } /** * Getting a wiki page * http://www.redmine.org/projects/redmine/wiki/Rest_WikiPages#Getting-a-wiki-page */ Redmine.prototype.wiki_by_title = function(id, title, params) { return this.request('GET', `/projects/${id}/wiki/${title}.json`, params) } /** * Getting an old version of a wiki page * http://www.redmine.org/projects/redmine/wiki/Rest_WikiPages#Getting-an-old-version-of-a-wiki-page */ Redmine.prototype.wiki_history_by_title = function(id, title, version, params) { return this.request( 'GET', `/projects/${id}/wiki/${title}/${version}.json`, params ) } /** * Creating or updating a wiki page * http://www.redmine.org/projects/redmine/wiki/Rest_WikiPages#Creating-or-updating-a-wiki-page */ Redmine.prototype.create_wiki = function(id, title, params) { return this.request('PUT', `/projects/${id}/wiki/${title}.json`, params) } /** * Deletes the issue category of given id. * http://www.redmine.org/projects/redmine/wiki/Rest_IssueCategories#DELETE */ Redmine.prototype.delete_wiki = function(id, title) { return this.request('DELETE', `/projects/${id}/wiki/${title}.json`, {}) } // REST API for Queries (Alpha) /** * Returns the list of all custom queries visible by the user (public and private queries) for all projects. * http://www.redmine.org/projects/redmine/wiki/Rest_Queries#GET */ Redmine.prototype.queries = function(params) { return this.request('GET', '/queries.json', params) } // REST API for Attachments (Beta) /** * Returns the description of the attachment of given id. * The file can actually be downloaded at the URL given by the content_url attribute in the response. * http://www.redmine.org/projects/redmine/wiki/Rest_Attachments#GET */ Redmine.prototype.attachment_by_id = function(id) { return this.request('GET', `/attachments/${id}.json`, {}) } /** * Updates attachments. * (Not documented yet. See #12181 for details) * https://www.redmine.org/projects/redmine/wiki/Rest_Attachments#PATCH */ Redmine.prototype.update_attachment = function(id, params) { return this.request('PATCH', `/attachments/${id}.json`, params) } // REST API for Issue Statuses (Alpha) /** * Returns the list of all issue statuses. * http://www.redmine.org/projects/redmine/wiki/Rest_IssueStatuses#GET */ Redmine.prototype.issue_statuses = function() { return this.request('GET', '/issue_statuses.json', {}) } // REST API for Trackers (Alpha) /** * Returns the list of all trackers. * http://www.redmine.org/projects/redmine/wiki/Rest_Trackers#GET */ Redmine.prototype.trackers = function() { return this.request('GET', '/trackers.json', {}) } // REST API for Enumerations (Alpha) /** * Returns the list of issue priorities. * http://www.redmine.org/projects/redmine/wiki/Rest_Enumerations#GET */ Redmine.prototype.issue_priorities = function() { return this.request('GET', '/enumerations/issue_priorities.json', {}) } /** * Returns the list of time entry activities. * http://www.redmine.org/projects/redmine/wiki/Rest_Enumerations#GET-2 */ Redmine.prototype.time_entry_activities = function() { return this.request('GET', '/enumerations/time_entry_activities.json', {}) } // REST API for Issue Categories (Alpha) /** * Returns the issue categories available for the project of given id or identifier (:project_id). * http://www.redmine.org/projects/redmine/wiki/Rest_IssueCategories#GET */ Redmine.prototype.issue_categories_by_project_id = function(id) { return this.request('GET', `/projects/${id}/issue_categories.json`, {}) } /** * Creates an issue category for the project of given id or identifier (:project_id). * http://www.redmine.org/projects/redmine/wiki/Rest_IssueCategories#POST */ Redmine.prototype.create_issue_category = function(id, params) { return this.request('POST', `/projects/${id}/issue_categories.json`, params) } /** * Returns the issue category of given id. * http://www.redmine.org/projects/redmine/wiki/Rest_IssueCategories#GET-2 */ Redmine.prototype.issue_category_by_id = function(id) { return this.request('GET', `/issue_categories/${id}.json`, {}) } /** * Updates the issue category of given id * http://www.redmine.org/projects/redmine/wiki/Rest_IssueCategories#PUT */ Redmine.prototype.update_issue_category = function(id, params) { return this.request('PUT', `/issue_categories/${id}.json`, params) } /** * Deletes the issue category of given id. * http://www.redmine.org/projects/redmine/wiki/Rest_IssueCategories#DELETE */ Redmine.prototype.delete_issue_category = function(id) { return this.request('DELETE', `/issue_categories/${id}.json`, {}) } // REST API for Roles (Alpha) /** * Returns the list of roles. * http://www.redmine.org/projects/redmine/wiki/Rest_Roles#GET */ Redmine.prototype.roles = function() { return this.request('GET', '/roles.json', {}) } /** * Returns the list of permissions for a given role * http://www.redmine.org/projects/redmine/wiki/Rest_Roles#GET-2 */ Redmine.prototype.role_by_id = function(id) { return this.request('GET', `/roles/${id}.json`, {}) } // REST API for Groups (Alpha) /** * Returns the list of Groups * http://www.redmine.org/projects/redmine/wiki/Rest_Groups#groupsformat */ Redmine.prototype.groups = function() { return this.request('GET', '/groups.json', {}) } /** * Creates a Group * http://www.redmine.org/projects/redmine/wiki/Rest_Groups#POST */ Redmine.prototype.create_group = function(params) { return this.request('POST', '/groups.json', params) } /** * Returns details of a group. * http://www.redmine.org/projects/redmine/wiki/Rest_Groups#GET-2 */ Redmine.prototype.group_by_id = function(id, params) { return this.request('GET', `/groups/${id}.json`, params) } /** * Updates an existing group * http://www.redmine.org/projects/redmine/wiki/Rest_Groups#PUT */ Redmine.prototype.update_group = function(id, params) { return this.request('PUT', `/groups/${id}.json`, params) } /** * Deletes an existing group * http://www.redmine.org/projects/redmine/wiki/Rest_Groups#DELETE */ Redmine.prototype.delete_group = function(id) { return this.request('DELETE', `/groups/${id}.json`, {}) } /** * Adds an existing user to a group * http://www.redmine.org/projects/redmine/wiki/Rest_Groups#POST-2 */ Redmine.prototype.add_user_to_group = function(groupId, userId) { const params = { user_id: userId } return this.request('POST', `/groups/${groupId}/users.json`, params) } /** * Removes a user from a group * http://www.redmine.org/projects/redmine/wiki/Rest_Groups#DELETE-2 */ Redmine.prototype.remove_user_from_group = function(groupId, userId) { return this.request('DELETE', `/groups/${groupId}/users/${userId}.json`, {}) } // REST API for Custom Fields (Alpha) /** * Get custom fields * http://www.redmine.org/projects/redmine/wiki/Rest_CustomFields#GET */ Redmine.prototype.custom_fields = function() { return this.request('GET', '/custom_fields.json', {}) } // REST API for Search (Alpha) // http://www.redmine.org/projects/redmine/wiki/Rest_Search // Not documented yet. // REST API for Common (Alpha) /** * upload a file to redmine * http://www.redmine.org/projects/redmine/wiki/Rest_WikiPages#Attaching-files */ Redmine.prototype.upload = function(content) { return this.request('POST', '/uploads.json', content) } module.exports = Redmine