Stackedit/src/services/providers/helpers/gitlabHelper.js

212 lines
5.0 KiB
JavaScript

import utils from '../../utils';
import networkSvc from '../../networkSvc';
import store from '../../../store';
import userSvc from '../../userSvc';
import badgeSvc from '../../badgeSvc';
const request = ({ accessToken, serverUrl }, options) => networkSvc.request({
...options,
url: `${serverUrl}/api/v4/${options.url}`,
headers: {
...options.headers || {},
Authorization: `Bearer ${accessToken}`,
},
})
.then(res => res.body);
const getCommitMessage = (name, path) => {
const message = store.getters['data/computedSettings'].git[name];
return message.replace(/{{path}}/g, path);
};
/**
* https://docs.gitlab.com/ee/api/users.html#for-user
*/
const subPrefix = 'gl';
userSvc.setInfoResolver('gitlab', subPrefix, async (sub) => {
try {
const [, serverUrl, id] = sub.match(/^(.+)\/([^/]+)$/);
const user = (await networkSvc.request({
url: `${serverUrl}/api/v4/users/${id}`,
})).body;
const uniqueSub = `${serverUrl}/${user.id}`;
return {
id: `${subPrefix}:${uniqueSub}`,
name: user.username,
imageUrl: user.avatar_url || '',
};
} catch (err) {
if (err.status !== 404) {
throw new Error('RETRY');
}
throw err;
}
});
export default {
subPrefix,
/**
* https://docs.gitlab.com/ee/api/oauth2.html
*/
async startOauth2(serverUrl, applicationId, sub = null, silent = false) {
const { accessToken } = await networkSvc.startOauth2(
`${serverUrl}/oauth/authorize`,
{
client_id: applicationId,
response_type: 'token',
scope: 'api',
},
silent,
);
// Call the user info endpoint
const user = await request({ accessToken, serverUrl }, {
url: 'user',
});
const uniqueSub = `${serverUrl}/${user.id}`;
userSvc.addUserInfo({
id: `${subPrefix}:${uniqueSub}`,
name: user.username,
imageUrl: user.avatar_url || '',
});
// Check the returned sub consistency
if (sub && uniqueSub !== sub) {
throw new Error('GitLab account ID not expected.');
}
// Build token object including scopes and sub
const token = {
accessToken,
name: user.username,
serverUrl,
sub: uniqueSub,
};
// Add token to gitlab tokens
store.dispatch('data/addGitlabToken', token);
return token;
},
async addAccount(serverUrl, applicationId, sub = null) {
const token = await this.startOauth2(serverUrl, applicationId, sub);
badgeSvc.addBadge('addGitLabAccount');
return token;
},
/**
* https://docs.gitlab.com/ee/api/projects.html#get-single-project
*/
async getProjectId(token, { projectPath, projectId }) {
if (projectId) {
return projectId;
}
const project = await request(token, {
url: `projects/${encodeURIComponent(projectPath)}`,
});
return project.id;
},
/**
* https://docs.gitlab.com/ee/api/repositories.html#list-repository-tree
*/
async getTree({
token,
projectId,
branch,
}) {
return request(token, {
url: `projects/${encodeURIComponent(projectId)}/repository/tree`,
params: {
ref: branch,
recursive: true,
per_page: 9999,
},
});
},
/**
* https://docs.gitlab.com/ee/api/commits.html#list-repository-commits
*/
async getCommits({
token,
projectId,
branch,
path,
}) {
return request(token, {
url: `projects/${encodeURIComponent(projectId)}/repository/commits`,
params: {
ref_name: branch,
path,
},
});
},
/**
* https://docs.gitlab.com/ee/api/repository_files.html#create-new-file-in-repository
* https://docs.gitlab.com/ee/api/repository_files.html#update-existing-file-in-repository
*/
async uploadFile({
token,
projectId,
branch,
path,
content,
sha,
}) {
return request(token, {
method: sha ? 'PUT' : 'POST',
url: `projects/${encodeURIComponent(projectId)}/repository/files/${encodeURIComponent(path)}`,
body: {
commit_message: getCommitMessage(sha ? 'updateFileMessage' : 'createFileMessage', path),
content,
last_commit_id: sha,
branch,
},
});
},
/**
* https://docs.gitlab.com/ee/api/repository_files.html#delete-existing-file-in-repository
*/
async removeFile({
token,
projectId,
branch,
path,
sha,
}) {
return request(token, {
method: 'DELETE',
url: `projects/${encodeURIComponent(projectId)}/repository/files/${encodeURIComponent(path)}`,
body: {
commit_message: getCommitMessage('deleteFileMessage', path),
last_commit_id: sha,
branch,
},
});
},
/**
* https://docs.gitlab.com/ee/api/repository_files.html#get-file-from-repository
*/
async downloadFile({
token,
projectId,
branch,
path,
}) {
const res = await request(token, {
url: `projects/${encodeURIComponent(projectId)}/repository/files/${encodeURIComponent(path)}`,
params: { ref: branch },
});
return {
sha: res.last_commit_id,
data: utils.decodeBase64(res.content),
};
},
};