refactor: adjust code to new TSLint rules

This commit is contained in:
Karl-Philipp Wulfert
2019-11-19 12:06:54 +01:00
parent 8a9ab5c041
commit edca51be10
3 changed files with 113 additions and 108 deletions

View File

@@ -34,17 +34,12 @@ import {
TreeFile,
} from './types';
/**
* Instance of logger
*/
export const logger = new Logger();
/**
* Sleep for a number of milliseconds
*
* @param ms Number of milliseconds to wait
*/
export function sleep(ms: number) {
export async function sleep(ms: number): Promise<void> {
return new Promise((resolve) => setTimeout(resolve, ms));
}
@@ -55,7 +50,7 @@ export interface ApiRequestOptions {
/**
* Data to be sent with the request
*/
data?: any;
data?: object | null;
/**
* HTTP verb to use for the request
@@ -124,10 +119,10 @@ export class Api {
* @param userId ID of the user
* @param accessLevel Access level for the new member in the scope
*/
public addMember(scope: MembershipScope,
id: number,
userId: number,
accessLevel: AccessLevel): Promise<Member> {
public async addMember(scope: MembershipScope,
id: number,
userId: number,
accessLevel: AccessLevel): Promise<Member> {
return this.makeGitLabAPIRequest(
`${scope}/${id}/members`,
{
@@ -137,7 +132,7 @@ export class Api {
},
method: 'POST',
},
);
) as Promise<Member>;
}
/**
@@ -147,7 +142,7 @@ export class Api {
* @param title Title of the issue
* @param description Description of the issue (can contain slash commands)
*/
public createIssue(projectId: number, title: string, description: string): Promise<Issue> {
public async createIssue(projectId: number, title: string, description: string): Promise<Issue> {
return this.makeGitLabAPIRequest(
`projects/${projectId}/issues`,
{
@@ -157,7 +152,7 @@ export class Api {
},
method: 'POST',
},
);
) as Promise<Issue>;
}
/**
@@ -168,22 +163,23 @@ export class Api {
* @param description Description of the label to create
* @param color Color of the label to create
*/
public createLabel(projectId: number, name: string, description?: string, color?: string): Promise<Label> {
if (typeof color !== 'string' || !color.match(/^#[0-9a-fA-F]{3,6}$/)) {
color = '#000000';
public async createLabel(projectId: number, name: string, description?: string, color?: string): Promise<Label> {
let _color = '#000000';
if (typeof color !== 'string' || !/^#[0-9a-fA-F]{3,6}$/.test(color)) {
_color = '#000000';
}
return this.makeGitLabAPIRequest(
`projects/${projectId}/labels`,
{
data: {
color: color,
description: description,
name: name,
color: _color,
description,
name,
},
method: 'POST',
},
);
) as Promise<Label>;
}
/**
@@ -192,10 +188,10 @@ export class Api {
* @param projectId Project ID to create milestone in
* @param title Title of the milestone to create
*/
public createMilestone(projectId: number, title: string): Promise<void> {
public async createMilestone(projectId: number, title: string): Promise<void> {
return this.makeGitLabAPIRequest(`projects/${projectId}/milestones?title=${title}`, {
method: 'POST',
});
}) as Promise<void>;
}
/**
@@ -206,7 +202,7 @@ export class Api {
* @param iid IID of the issue/merge request to create the note in
* @param body Body of the note to create
*/
public createNote(projectId: number, scope: Scope, iid: number, body: string): Promise<void> {
public async createNote(projectId: number, scope: Scope, iid: number, body: string): Promise<void> {
return this.makeGitLabAPIRequest(
`projects/${projectId}/${scope}/${iid}/notes`,
{
@@ -215,7 +211,7 @@ export class Api {
},
method: 'POST',
},
);
) as Promise<void>;
}
/**
@@ -224,13 +220,13 @@ export class Api {
* @param projectId ID of the project to delete the label from
* @param name Name of the label to delete
*/
public deleteLabel(projectId: number, name: string): Promise<void> {
public async deleteLabel(projectId: number, name: string): Promise<void> {
return this.makeGitLabAPIRequest(
`projects/${projectId}/labels?name=${name}`,
{
method: 'DELETE',
},
);
) as Promise<void>;
}
/**
@@ -240,8 +236,8 @@ export class Api {
* @param id ID of the group or project
* @param userId ID of the user
*/
public deleteMember(scope: MembershipScope, id: number, userId: number): Promise<void> {
return this.makeGitLabAPIRequest(`${scope}/${id}/members/${userId}`, {method: 'DELETE'});
public async deleteMember(scope: MembershipScope, id: number, userId: number): Promise<void> {
return this.makeGitLabAPIRequest(`${scope}/${id}/members/${userId}`, {method: 'DELETE'}) as Promise<void>;
}
/**
@@ -251,8 +247,8 @@ export class Api {
* @param name Name of the label to edit
* @param newValues New values for the label
*/
public editLabel(projectId: number, name: string, newValues: Partial<Label>): Promise<Label> {
if (typeof newValues.color === 'string' && !newValues.color.match(/^#[0-9a-fA-F]{3,6}$/)) {
public async editLabel(projectId: number, name: string, newValues: Partial<Label>): Promise<Label> {
if (typeof newValues.color === 'string' && !/^#[0-9a-fA-F]{3,6}$/.test(newValues.color)) {
newValues.color = undefined;
}
@@ -267,7 +263,7 @@ export class Api {
},
method: 'POST',
},
);
) as Promise<Label>;
}
/**
@@ -278,10 +274,10 @@ export class Api {
* @param userId ID of the user
* @param accessLevel Access level for the member in the scope
*/
public editMember(scope: MembershipScope,
id: number,
userId: number,
accessLevel: AccessLevel): Promise<Member> {
public async editMember(scope: MembershipScope,
id: number,
userId: number,
accessLevel: AccessLevel): Promise<Member> {
return this.makeGitLabAPIRequest(
`${scope}/${id}/members`,
{
@@ -291,7 +287,7 @@ export class Api {
},
method: 'PUT',
},
);
) as Promise<Member>;
}
/**
@@ -299,8 +295,8 @@ export class Api {
*
* @param projectId Project ID to get branches for
*/
public getBranchesForProject(projectId: number): Promise<Branch[]> {
return this.makeGitLabAPIRequest(`projects/${projectId}/repository/branches`);
public async getBranchesForProject(projectId: number): Promise<Branch[]> {
return this.makeGitLabAPIRequest(`projects/${projectId}/repository/branches`) as Promise<Branch[]>;
}
/**
@@ -310,11 +306,11 @@ export class Api {
* @param filePath Path to the file - url encoded
* @param commitish Commitish of the file
*/
public getFile(projectId: number, filePath: string, commitish: string): Promise<any> {
return this.makeGitLabAPIRequest(
`projects/${projectId}/repository/files/` +
encodeURIComponent(filePath).replace('.', '%2E') + '/raw?ref=' + encodeURIComponent(commitish),
);
public async getFile(projectId: number, filePath: string, commitish: string): Promise<unknown> {
const fileIdentifier = `${encodeURIComponent(filePath)
.replace('.', '%2E')}/raw?ref=${encodeURIComponent(commitish)}`;
return this.makeGitLabAPIRequest(`projects/${projectId}/repository/files/${fileIdentifier}`) as Promise<unknown>;
}
/**
@@ -322,8 +318,8 @@ export class Api {
*
* @param projectId ID of the project
*/
public getFileList(projectId: number): Promise<TreeFile[]> {
return this.makeGitLabAPIRequest(`projects/${projectId}/repository/tree`);
public async getFileList(projectId: number): Promise<TreeFile[]> {
return this.makeGitLabAPIRequest(`projects/${projectId}/repository/tree`) as Promise<TreeFile[]>;
}
/**
@@ -331,7 +327,7 @@ export class Api {
*
* @param options Options to get issues
*/
public getIssues(options: ApiGetIssuesOptions = {}): Promise<Issue[]> {
public async getIssues(options: ApiGetIssuesOptions = {}): Promise<Issue[]> {
// start to build request url
let requestUrl = 'issues';
@@ -355,7 +351,7 @@ export class Api {
// divider = '&';
}
return this.makeGitLabAPIRequest(requestUrl);
return this.makeGitLabAPIRequest(requestUrl) as Promise<Issue[]>;
}
/**
@@ -363,8 +359,8 @@ export class Api {
*
* @param projectId ID of the project to get the labels for
*/
public getLabels(projectId: number): Promise<Label[]> {
return this.makeGitLabAPIRequest(`projects/${projectId}/labels`);
public async getLabels(projectId: number): Promise<Label[]> {
return this.makeGitLabAPIRequest(`projects/${projectId}/labels`) as Promise<Label[]>;
}
/**
@@ -373,8 +369,8 @@ export class Api {
* @param scope MembershipScope of the ID
* @param id ID of the group or project
*/
public getMembers(scope: MembershipScope, id: number): Promise<Member[]> {
return this.makeGitLabAPIRequest(`${scope}/${id}/members`);
public async getMembers(scope: MembershipScope, id: number): Promise<Member[]> {
return this.makeGitLabAPIRequest(`${scope}/${id}/members`) as Promise<Member[]>;
}
/**
@@ -383,8 +379,9 @@ export class Api {
* @param projectId ID of the project the merge request belongs to
* @param mergeRequestIid IID of the merge request
*/
public getMergeRequestApproval(projectId: number, mergeRequestIid: number): Promise<MergeRequestApproval> {
return this.makeGitLabAPIRequest(`/projects/${projectId}/merge_requests/${mergeRequestIid}/approvals`);
public async getMergeRequestApproval(projectId: number, mergeRequestIid: number): Promise<MergeRequestApproval> {
return this.makeGitLabAPIRequest(`/projects/${projectId}/merge_requests/${mergeRequestIid}/approvals`) as
Promise<MergeRequestApproval>;
}
/**
@@ -393,10 +390,10 @@ export class Api {
* @param projectId ID of the project the merge request belongs to
* @param mergeRequestIid IID of the merge request
*/
public getMergeRequestDiscussions(projectId: number, mergeRequestIid: number): Promise<Discussion[]> {
public async getMergeRequestDiscussions(projectId: number, mergeRequestIid: number): Promise<Discussion[]> {
return this.makeGitLabAPIRequest(
`projects/${projectId}/merge_requests/${mergeRequestIid}/discussions`,
);
) as Promise<Discussion[]>;
}
/**
@@ -406,15 +403,17 @@ export class Api {
* @param id ID of the group or project
* @param state State to filter the merge requests by
*/
public getMergeRequests(scope: MembershipScope,
id: number,
state: MergeRequestState | MergeRequestState[]): Promise<MergeRequest[]> {
public async getMergeRequests(scope: MembershipScope,
id: number,
state: MergeRequestState | MergeRequestState[]): Promise<MergeRequest[]> {
let _state = state;
// join a list of states with commas
if (Array.isArray(state)) {
state = state.join(',') as MergeRequestState;
_state = state.join(',') as MergeRequestState;
}
return this.makeGitLabAPIRequest(`${scope}/${id}/merge_requests?state=${state}`);
return this.makeGitLabAPIRequest(`${scope}/${id}/merge_requests?state=${_state}`) as Promise<MergeRequest[]>;
}
/**
@@ -422,8 +421,8 @@ export class Api {
*
* @param projectId Project ID to get milestones for
*/
public getMilestonesForProject(projectId: number): Promise<Milestone[]> {
return this.makeGitLabAPIRequest(`projects/${projectId}/milestones`);
public async getMilestonesForProject(projectId: number): Promise<Milestone[]> {
return this.makeGitLabAPIRequest(`projects/${projectId}/milestones`) as Promise<Milestone[]>;
}
/**
@@ -431,8 +430,8 @@ export class Api {
*
* @param groupId Group ID to get projects for
*/
public getProjectsForGroup(groupId: number): Promise<Project[]> {
return this.makeGitLabAPIRequest(`groups/${groupId}/projects`);
public async getProjectsForGroup(groupId: number): Promise<Project[]> {
return this.makeGitLabAPIRequest(`groups/${groupId}/projects`) as Promise<Project[]>;
}
/**
@@ -440,8 +439,8 @@ export class Api {
*
* @param groupId Group ID to get subgroups for
*/
public getSubGroupsForGroup(groupId: number): Promise<Group[]> {
return this.makeGitLabAPIRequest(`/groups/${groupId}/subgroups`);
public async getSubGroupsForGroup(groupId: number): Promise<Group[]> {
return this.makeGitLabAPIRequest(`/groups/${groupId}/subgroups`) as Promise<Group[]>;
}
/**
@@ -449,60 +448,60 @@ export class Api {
*
* @param projectId ID of the project to get the tags for
*/
public getTags(projectId: number): Promise<Tag[]> {
public async getTags(projectId: number): Promise<Tag[]> {
return this.makeGitLabAPIRequest(
`projects/${projectId}/repository/tags`,
);
) as Promise<Tag[]>;
}
/**
* Query a GitLab API URL
*
* @param url GitLab API URL to query
* @param _options HTTP method/verb
* @param options HTTP method/verb
*/
public async makeGitLabAPIRequest(url: string, _options?: ApiRequestOptions): Promise<any> {
public async makeGitLabAPIRequest(url: string, options?: ApiRequestOptions): Promise<unknown> {
// remove leading slash
url = url.replace(/^\/+/g, '');
const _url = url.replace(/^\/+/g, '');
const options: Required<ApiRequestOptions> = {
data: undefined,
const _options: Required<ApiRequestOptions> = {
data: null,
method: 'GET',
retryOnAnyError: false,
tries: 5,
..._options,
...options,
};
if (typeof options.method === 'string' && ['DELETE', 'GET', 'POST', 'PUT'].indexOf(options.method) === -1) {
options.method = 'GET';
if (['DELETE', 'GET', 'POST', 'PUT'].includes(_options.method)) {
_options.method = 'GET';
}
let concatenator = '&';
if (url.indexOf('?') === -1) {
if (_url.indexOf('?') === -1) {
concatenator = '?';
}
let apiResult: any;
let apiResult: unknown;
let totalPages = 1;
let currentPage = 0;
while (++currentPage <= totalPages) {
if (currentPage > 1) {
logger.info(`Automatically paging call to '${url}'... Getting page ${currentPage} of ${totalPages}.`);
Logger.info(`Automatically paging call to '${_url}'... Getting page ${currentPage} of ${totalPages}.`);
}
let body;
let tries = 0;
while (typeof body === 'undefined' && tries++ < options.tries) {
while (typeof body === 'undefined' && tries++ < _options.tries) {
try {
const requestUrl = url + concatenator + 'page=' + currentPage + '&per_page=100';
const requestUrl = `${_url}${concatenator}page=${currentPage}&per_page=100`;
body = await request(this.rootUrl + requestUrl, {
form: typeof options.data !== 'undefined' ? options.data : undefined,
body = await request(`${this.rootUrl}${requestUrl}`, {
form: _options.data !== null ? _options.data : undefined,
headers: {'PRIVATE-TOKEN': this.privateToken},
json: true,
method: options.method,
method: _options.method,
timeout: 60000,
transform: (bodyToTransform, response) => {
const xTotalPages = response.headers['x-total-pages'];
@@ -515,11 +514,12 @@ export class Api {
},
});
} catch (error) {
if (error.error.includes('not responding') || options.retryOnAnyError) {
if (error.error.includes('not responding') || _options.retryOnAnyError) {
const seconds = 5;
logger.warn(`GitLab was not responding. Waiting ${seconds}s and retrying...`);
Logger.warn(`GitLab was not responding. Waiting ${seconds}s and retrying...`);
// tslint:disable-next-line:no-magic-numbers
await sleep(seconds * 1000);
continue;
@@ -529,7 +529,7 @@ export class Api {
}
}
if (options.method === 'DELETE') {
if (_options.method === 'DELETE') {
return;
}
@@ -551,14 +551,14 @@ export class Api {
* @param projectId ID of the project the branch belongs to
* @param branch Branch to protect
*/
public protectBranch(projectId: number, branch: string): Promise<Branch> {
public async protectBranch(projectId: number, branch: string): Promise<Branch> {
return this.makeGitLabAPIRequest(
/* tslint:disable-next-line:max-line-length */
`projects/${projectId}/repository/branches/${branch}/protect?developers_can_push=false&developers_can_merge=false`,
{
method: 'PUT',
},
);
) as Promise<Branch>;
}
/**
@@ -567,13 +567,13 @@ export class Api {
* @param issue Issue to set milestone for
* @param userId ID of the milestone to set for the issue
*/
public setAssigneeForIssue(issue: Issue, userId: number): Promise<Issue> {
public async setAssigneeForIssue(issue: Issue, userId: number): Promise<Issue> {
return this.makeGitLabAPIRequest(
`projects/${issue.project_id}/issues/${issue.iid}?assignee_ids=${userId}`,
{
method: 'PUT',
},
);
) as Promise<Issue>;
}
/**
@@ -582,14 +582,14 @@ export class Api {
* @param issue Issue to set milestone for
* @param milestoneId ID of the milestone to set for the issue
*/
public setMilestoneForIssue(issue: Issue, milestoneId: number): Promise<Issue> {
public async setMilestoneForIssue(issue: Issue, milestoneId: number): Promise<Issue> {
if (milestoneId === null) {
return this.makeGitLabAPIRequest(
`projects/${issue.project_id}/issues/${issue.iid}?milestone_id=`,
{
method: 'PUT',
},
);
) as Promise<Issue>;
}
return this.makeGitLabAPIRequest(
@@ -597,6 +597,6 @@ export class Api {
{
method: 'PUT',
},
);
) as Promise<Issue>;
}
}

View File

@@ -12,12 +12,14 @@
* You should have received a copy of the GNU General Public License along with
* this program. If not, see <https://www.gnu.org/licenses/>.
*/
import {Logger} from '@openstapps/logger';
import * as commander from 'commander';
import {readFileSync} from 'fs';
import {join} from 'path';
import {Api, ApiRequestOptions, logger} from './api';
import {Api, ApiRequestOptions} from './api';
const pkgJson = JSON.parse(readFileSync(join(__dirname, '..', 'package.json')).toString());
const pkgJson = JSON.parse(readFileSync(join(__dirname, '..', 'package.json'))
.toString());
commander
.version(pkgJson.version);
@@ -38,7 +40,7 @@ if (typeof commander.call === 'undefined') {
if (typeof commander.token === 'undefined') {
if (typeof process.env.GITLAB_PRIVATE_TOKEN === 'undefined') {
logger.error('You have to supply ');
Logger.warn('You probably want to supply a GitLab token either via option or environment variable (GITLAB_PRIVATE_TOKEN).');
}
commander.token = process.env.GITLAB_PRIVATE_TOKEN;
@@ -56,10 +58,11 @@ if (typeof commander.data !== 'undefined') {
options.data = JSON.parse(commander.data);
}
gitLabApi.makeGitLabAPIRequest(commander.call, options).then((result) => {
logger.ok(result);
process.exit(1);
}, (err) => {
logger.error(err);
process.exit(1);
});
gitLabApi.makeGitLabAPIRequest(commander.call, options)
.then((result) => {
Logger.ok(result);
process.exit(1);
}, async (err) => {
await Logger.error(err);
process.exit(1);
});

View File

@@ -13,6 +13,8 @@
* this program. If not, see <https://www.gnu.org/licenses/>.
*/
// tslint:disable:completed-docs
/**
* Scope of membership
*/
@@ -160,7 +162,7 @@ export interface Project {
public_jobs: boolean;
request_access_enabled: boolean;
shared_runners_enabled: boolean;
shared_with_groups: any[];
shared_with_groups: unknown[];
snippets_enabled: boolean;
ssh_url_to_repo: string;
star_count: number;
@@ -307,7 +309,7 @@ export interface MergeRequest extends ThingWithTimeStats {
export interface MergeRequestApproval {
approvals_left: number;
approvals_required: number;
approved_by: Array<{ user: User }>;
approved_by: Array<{ user: User; }>;
approver_groups: Group[];
approvers: User[];
created_at: string;
@@ -381,7 +383,7 @@ export interface Note {
new_path: string;
old_line: number | null;
old_path: string;
position_type: string,
position_type: string;
start_sha: string;
};
resolvable: boolean;