import createFlash from '~/flash'; import { __ } from '~/locale'; import axios from './lib/utils/axios_utils'; import { joinPaths } from './lib/utils/url_utility'; export const DEFAULT_PER_PAGE = 20; /** * Slow deprecation Notice: Please rather use for new calls * or during refactors /rest_api as this is doing named exports * which support treeshaking */ const Api = { DEFAULT_PER_PAGE, groupsPath: '/api/:version/groups.json', groupPath: '/api/:version/groups/:id', groupMembersPath: '/api/:version/groups/:id/members', groupMilestonesPath: '/api/:version/groups/:id/milestones', subgroupsPath: '/api/:version/groups/:id/subgroups', descendantGroupsPath: '/api/:version/groups/:id/descendant_groups', namespacesPath: '/api/:version/namespaces.json', groupInvitationsPath: '/api/:version/groups/:id/invitations', groupPackagesPath: '/api/:version/groups/:id/packages', projectPackagesPath: '/api/:version/projects/:id/packages', projectPackagePath: '/api/:version/projects/:id/packages/:package_id', projectPackageFilePath: '/api/:version/projects/:id/packages/:package_id/package_files/:package_file_id', groupProjectsPath: '/api/:version/groups/:id/projects.json', groupSharePath: '/api/:version/groups/:id/share', projectsPath: '/api/:version/projects.json', projectPath: '/api/:version/projects/:id', forkedProjectsPath: '/api/:version/projects/:id/forks', projectLabelsPath: '/:namespace_path/:project_path/-/labels', projectFileSchemaPath: '/:namespace_path/:project_path/-/schema/:ref/:filename', projectUsersPath: '/api/:version/projects/:id/users', projectInvitationsPath: '/api/:version/projects/:id/invitations', projectMembersPath: '/api/:version/projects/:id/members', projectMergeRequestsPath: '/api/:version/projects/:id/merge_requests', projectMergeRequestPath: '/api/:version/projects/:id/merge_requests/:mrid', projectMergeRequestChangesPath: '/api/:version/projects/:id/merge_requests/:mrid/changes', projectMergeRequestVersionsPath: '/api/:version/projects/:id/merge_requests/:mrid/versions', projectRunnersPath: '/api/:version/projects/:id/runners', projectProtectedBranchesPath: '/api/:version/projects/:id/protected_branches', projectProtectedBranchesNamePath: '/api/:version/projects/:id/protected_branches/:name', projectSearchPath: '/api/:version/projects/:id/search', projectSharePath: '/api/:version/projects/:id/share', projectMilestonesPath: '/api/:version/projects/:id/milestones', projectIssuePath: '/api/:version/projects/:id/issues/:issue_iid', mergeRequestsPath: '/api/:version/merge_requests', groupLabelsPath: '/api/:version/groups/:namespace_path/labels', issuableTemplatePath: '/:namespace_path/:project_path/templates/:type/:key', issuableTemplatesPath: '/:namespace_path/:project_path/templates/:type', projectTemplatePath: '/api/:version/projects/:id/templates/:type/:key', projectTemplatesPath: '/api/:version/projects/:id/templates/:type', userCountsPath: '/api/:version/user_counts', usersPath: '/api/:version/users.json', userPath: '/api/:version/users/:id', userStatusPath: '/api/:version/users/:id/status', userProjectsPath: '/api/:version/users/:id/projects', userPostStatusPath: '/api/:version/user/status', commitPath: '/api/:version/projects/:id/repository/commits/:sha', commitsPath: '/api/:version/projects/:id/repository/commits', applySuggestionPath: '/api/:version/suggestions/:id/apply', applySuggestionBatchPath: '/api/:version/suggestions/batch_apply', commitPipelinesPath: '/:project_id/commit/:sha/pipelines', branchSinglePath: '/api/:version/projects/:id/repository/branches/:branch', createBranchPath: '/api/:version/projects/:id/repository/branches', releasesPath: '/api/:version/projects/:id/releases', releasePath: '/api/:version/projects/:id/releases/:tag_name', releaseLinksPath: '/api/:version/projects/:id/releases/:tag_name/assets/links', releaseLinkPath: '/api/:version/projects/:id/releases/:tag_name/assets/links/:link_id', mergeRequestsPipeline: '/api/:version/projects/:id/merge_requests/:merge_request_iid/pipelines', adminStatisticsPath: '/api/:version/application/statistics', pipelineJobsPath: '/api/:version/projects/:id/pipelines/:pipeline_id/jobs', pipelineSinglePath: '/api/:version/projects/:id/pipelines/:pipeline_id', pipelinesPath: '/api/:version/projects/:id/pipelines/', createPipelinePath: '/api/:version/projects/:id/pipeline', environmentsPath: '/api/:version/projects/:id/environments', contextCommitsPath: '/api/:version/projects/:id/merge_requests/:merge_request_iid/context_commits', rawFilePath: '/api/:version/projects/:id/repository/files/:path/raw', issuePath: '/api/:version/projects/:id/issues/:issue_iid', tagsPath: '/api/:version/projects/:id/repository/tags', freezePeriodsPath: '/api/:version/projects/:id/freeze_periods', freezePeriodPath: '/api/:version/projects/:id/freeze_periods/:freeze_period_id', serviceDataIncrementCounterPath: '/api/:version/usage_data/increment_counter', serviceDataIncrementUniqueUsersPath: '/api/:version/usage_data/increment_unique_users', featureFlagUserLists: '/api/:version/projects/:id/feature_flags_user_lists', featureFlagUserList: '/api/:version/projects/:id/feature_flags_user_lists/:list_iid', containerRegistryDetailsPath: '/api/:version/registry/repositories/:id/', projectNotificationSettingsPath: '/api/:version/projects/:id/notification_settings', groupNotificationSettingsPath: '/api/:version/groups/:id/notification_settings', notificationSettingsPath: '/api/:version/notification_settings', deployKeysPath: '/api/:version/deploy_keys', secureFilesPath: '/api/:version/projects/:project_id/secure_files', dependencyProxyPath: '/api/:version/groups/:id/dependency_proxy/cache', group(groupId, callback = () => {}) { const url = Api.buildUrl(Api.groupPath).replace(':id', groupId); return axios.get(url).then(({ data }) => { callback(data); return data; }); }, groupPackages(id, options = {}) { const url = Api.buildUrl(this.groupPackagesPath).replace(':id', id); return axios.get(url, options); }, projectPackages(id, options = {}) { const url = Api.buildUrl(this.projectPackagesPath).replace(':id', id); return axios.get(url, options); }, buildProjectPackageUrl(projectId, packageId) { return Api.buildUrl(this.projectPackagePath) .replace(':id', projectId) .replace(':package_id', packageId); }, projectPackage(projectId, packageId) { const url = this.buildProjectPackageUrl(projectId, packageId); return axios.get(url); }, deleteProjectPackage(projectId, packageId) { const url = this.buildProjectPackageUrl(projectId, packageId); return axios.delete(url); }, deleteProjectPackageFile(projectId, packageId, fileId) { const url = Api.buildUrl(this.projectPackageFilePath) .replace(':id', projectId) .replace(':package_id', packageId) .replace(':package_file_id', fileId); return axios.delete(url); }, containerRegistryDetails(registryId, options = {}) { const url = Api.buildUrl(this.containerRegistryDetailsPath).replace(':id', registryId); return axios.get(url, options); }, groupMembers(id, options) { const url = Api.buildUrl(this.groupMembersPath).replace(':id', encodeURIComponent(id)); return axios.get(url, { params: { per_page: DEFAULT_PER_PAGE, ...options, }, }); }, inviteGroupMembers(id, data) { const url = Api.buildUrl(this.groupInvitationsPath).replace(':id', encodeURIComponent(id)); return axios.post(url, data); }, groupMilestones(id, options) { const url = Api.buildUrl(this.groupMilestonesPath).replace(':id', encodeURIComponent(id)); return axios.get(url, { params: { per_page: DEFAULT_PER_PAGE, ...options, }, }); }, /** * @deprecated This method will be removed soon. Use the * `getGroups` method in `~/rest_api` instead. */ groups(query, options, callback = () => {}) { const url = Api.buildUrl(Api.groupsPath); return axios .get(url, { params: { search: query, per_page: DEFAULT_PER_PAGE, ...options, }, }) .then(({ data }) => { callback(data); return data; }); }, groupLabels(namespace, options = {}) { const url = Api.buildUrl(Api.groupLabelsPath).replace(':namespace_path', namespace); return axios.get(url, options).then(({ data }) => data); }, // Return namespaces list. Filtered by query namespaces(query, callback) { const url = Api.buildUrl(Api.namespacesPath); return axios .get(url, { params: { search: query, per_page: DEFAULT_PER_PAGE, }, }) .then(({ data }) => callback(data)); }, /** * @deprecated This method will be removed soon. Use the * `getProjects` method in `~/rest_api` instead. */ projects(query, options, callback = () => {}) { const url = Api.buildUrl(Api.projectsPath); const defaults = { search: query, per_page: DEFAULT_PER_PAGE, simple: true, }; if (gon.current_user_id) { defaults.membership = true; } return axios .get(url, { params: { ...defaults, ...options }, }) .then(({ data, headers }) => { callback(data); return { data, headers }; }); }, projectUsers(projectPath, query = '', options = {}) { const url = Api.buildUrl(this.projectUsersPath).replace(':id', encodeURIComponent(projectPath)); return axios .get(url, { params: { search: query, per_page: DEFAULT_PER_PAGE, ...options, }, }) .then(({ data }) => data); }, inviteProjectMembers(id, data) { const url = Api.buildUrl(this.projectInvitationsPath).replace(':id', encodeURIComponent(id)); return axios.post(url, data); }, // Return single project project(projectPath) { const url = Api.buildUrl(Api.projectPath).replace(':id', encodeURIComponent(projectPath)); return axios.get(url); }, // Update a single project updateProject(projectPath, data) { const url = Api.buildUrl(Api.projectPath).replace(':id', encodeURIComponent(projectPath)); return axios.put(url, data); }, /** * Get all projects for a forked relationship to a specified project * @param {string} projectPath - Path or ID of a project * @param {Object} params - Get request parameters * @returns {Promise} - Request promise */ projectForks(projectPath, params) { const url = Api.buildUrl(Api.forkedProjectsPath).replace( ':id', encodeURIComponent(projectPath), ); return axios.get(url, { params }); }, /** * Get all merge requests for a project, eventually filtering based on * supplied parameters * @param projectPath * @param params * @returns {Promise} */ projectMergeRequests(projectPath, params = {}) { const url = Api.buildUrl(Api.projectMergeRequestsPath).replace( ':id', encodeURIComponent(projectPath), ); return axios.get(url, { params }); }, createProjectMergeRequest(projectPath, options) { const url = Api.buildUrl(Api.projectMergeRequestsPath).replace( ':id', encodeURIComponent(projectPath), ); return axios.post(url, options); }, // Return merge request for project projectMergeRequest(projectPath, mergeRequestId, params = {}) { const url = Api.buildUrl(Api.projectMergeRequestPath) .replace(':id', encodeURIComponent(projectPath)) .replace(':mrid', mergeRequestId); return axios.get(url, { params }); }, projectMergeRequestChanges(projectPath, mergeRequestId) { const url = Api.buildUrl(Api.projectMergeRequestChangesPath) .replace(':id', encodeURIComponent(projectPath)) .replace(':mrid', mergeRequestId); return axios.get(url); }, projectMergeRequestVersions(projectPath, mergeRequestId) { const url = Api.buildUrl(Api.projectMergeRequestVersionsPath) .replace(':id', encodeURIComponent(projectPath)) .replace(':mrid', mergeRequestId); return axios.get(url); }, projectRunners(projectPath, config = {}) { const url = Api.buildUrl(Api.projectRunnersPath).replace( ':id', encodeURIComponent(projectPath), ); return axios.get(url, config); }, projectProtectedBranches(id, query = '') { const url = Api.buildUrl(Api.projectProtectedBranchesPath).replace( ':id', encodeURIComponent(id), ); return axios .get(url, { params: { search: query, per_page: DEFAULT_PER_PAGE, }, }) .then(({ data }) => data); }, projectProtectedBranch(id, branchName) { const url = Api.buildUrl(Api.projectProtectedBranchesNamePath) .replace(':id', encodeURIComponent(id)) .replace(':name', branchName); return axios.get(url).then(({ data }) => data); }, projectSearch(id, options = {}) { const url = Api.buildUrl(Api.projectSearchPath).replace(':id', encodeURIComponent(id)); return axios.get(url, { params: { search: options.search, scope: options.scope, }, }); }, projectShareWithGroup(id, options = {}) { const url = Api.buildUrl(Api.projectSharePath).replace(':id', encodeURIComponent(id)); return axios.post(url, { expires_at: options.expires_at, group_access: options.group_access, group_id: options.group_id, }); }, projectMilestones(id, params = {}) { const url = Api.buildUrl(Api.projectMilestonesPath).replace(':id', encodeURIComponent(id)); return axios.get(url, { params, }); }, addProjectIssueAsTodo(projectId, issueIid) { const url = Api.buildUrl(Api.projectIssuePath) .replace(':id', encodeURIComponent(projectId)) .replace(':issue_iid', encodeURIComponent(issueIid)); return axios.post(`${url}/todo`); }, mergeRequests(params = {}) { const url = Api.buildUrl(Api.mergeRequestsPath); return axios.get(url, { params }); }, newLabel(namespacePath, projectPath, data, callback) { let url; let payload; if (projectPath) { url = Api.buildUrl(Api.projectLabelsPath) .replace(':namespace_path', namespacePath) .replace(':project_path', projectPath); payload = { label: data, }; } else { url = Api.buildUrl(Api.groupLabelsPath).replace(':namespace_path', namespacePath); // groupLabelsPath uses public API which accepts // `name` and `color` props. payload = { name: data.title, color: data.color, }; } return axios .post(url, { ...payload, }) .then((res) => callback(res.data)) .catch((e) => callback(e.response.data)); }, // Return group projects list. Filtered by query groupProjects(groupId, query, options, callback = () => {}, useCustomErrorHandler = false) { const url = Api.buildUrl(Api.groupProjectsPath).replace(':id', groupId); const defaults = { search: query, per_page: DEFAULT_PER_PAGE, }; return axios .get(url, { params: { ...defaults, ...options }, }) .then(({ data, headers }) => { callback(data); return { data, headers }; }) .catch((error) => { if (useCustomErrorHandler) { throw error; } createFlash({ message: __('Something went wrong while fetching projects'), }); callback(); }); }, groupShareWithGroup(id, options = {}) { const url = Api.buildUrl(Api.groupSharePath).replace(':id', encodeURIComponent(id)); return axios.post(url, { expires_at: options.expires_at, group_access: options.group_access, group_id: options.group_id, }); }, commit(id, sha, params = {}) { const url = Api.buildUrl(this.commitPath) .replace(':id', encodeURIComponent(id)) .replace(':sha', encodeURIComponent(sha)); return axios.get(url, { params }); }, commitMultiple(id, data) { // see https://docs.gitlab.com/ee/api/commits.html#create-a-commit-with-multiple-files-and-actions const url = Api.buildUrl(Api.commitsPath).replace(':id', encodeURIComponent(id)); return axios.post(url, JSON.stringify(data), { headers: { 'Content-Type': 'application/json; charset=utf-8', }, }); }, applySuggestion(id, message = '') { const url = Api.buildUrl(Api.applySuggestionPath).replace(':id', encodeURIComponent(id)); const params = { commit_message: message }; return axios.put(url, params); }, applySuggestionBatch(ids, message) { const url = Api.buildUrl(Api.applySuggestionBatchPath); return axios.put(url, { ids, commit_message: message }); }, commitPipelines(projectId, sha) { const encodedProjectId = projectId .split('/') .map((fragment) => encodeURIComponent(fragment)) .join('/'); const url = Api.buildUrl(Api.commitPipelinesPath) .replace(':project_id', encodedProjectId) .replace(':sha', encodeURIComponent(sha)); return axios.get(url); }, branchSingle(id, branch) { const url = Api.buildUrl(Api.branchSinglePath) .replace(':id', encodeURIComponent(id)) .replace(':branch', encodeURIComponent(branch)); return axios.get(url); }, projectTemplate(id, type, key, options, callback) { const url = Api.buildUrl(this.projectTemplatePath) .replace(':id', encodeURIComponent(id)) .replace(':type', type) .replace(':key', encodeURIComponent(key)); return axios.get(url, { params: options }).then((res) => { if (callback) callback(res.data); return res; }); }, projectTemplates(id, type, params = {}, callback) { const url = Api.buildUrl(this.projectTemplatesPath) .replace(':id', encodeURIComponent(id)) .replace(':type', type); return axios.get(url, { params }).then((res) => { if (callback) callback(res.data); return res; }); }, issueTemplate(namespacePath, projectPath, key, type, callback) { const url = this.buildIssueTemplateUrl( Api.issuableTemplatePath, type, projectPath, namespacePath, ).replace(':key', encodeURIComponent(key)); return axios .get(url) .then(({ data }) => callback(null, data)) .catch(callback); }, issueTemplates(namespacePath, projectPath, type, callback) { const url = this.buildIssueTemplateUrl( Api.issuableTemplatesPath, type, projectPath, namespacePath, ); return axios .get(url) .then(({ data }) => callback(null, data)) .catch(callback); }, buildIssueTemplateUrl(path, type, projectPath, namespacePath) { return Api.buildUrl(path) .replace(':type', type) .replace(':project_path', projectPath) .replace(':namespace_path', namespacePath); }, /** * @deprecated This method will be removed soon. Use the * `getUsers` method in `~/rest_api` instead. */ users(query, options) { const url = Api.buildUrl(this.usersPath); return axios.get(url, { params: { search: query, per_page: DEFAULT_PER_PAGE, ...options, }, }); }, /** * @deprecated This method will be removed soon. Use the * `getUser` method in `~/rest_api` instead. */ user(id, options) { const url = Api.buildUrl(this.userPath).replace(':id', encodeURIComponent(id)); return axios.get(url, { params: options, }); }, /** * @deprecated This method will be removed soon. Use the * `getUserCounts` method in `~/rest_api` instead. */ userCounts() { const url = Api.buildUrl(this.userCountsPath); return axios.get(url); }, /** * @deprecated This method will be removed soon. Use the * `getUserStatus` method in `~/rest_api` instead. */ userStatus(id, options) { const url = Api.buildUrl(this.userStatusPath).replace(':id', encodeURIComponent(id)); return axios.get(url, { params: options, }); }, /** * @deprecated This method will be removed soon. Use the * `getUserProjects` method in `~/rest_api` instead. */ userProjects(userId, query, options, callback) { const url = Api.buildUrl(Api.userProjectsPath).replace(':id', userId); const defaults = { search: query, per_page: DEFAULT_PER_PAGE, }; return axios .get(url, { params: { ...defaults, ...options }, }) .then(({ data }) => callback(data)) .catch(() => createFlash({ message: __('Something went wrong while fetching projects'), }), ); }, branches(id, query = '', options = {}) { const url = Api.buildUrl(this.createBranchPath).replace(':id', encodeURIComponent(id)); return axios.get(url, { params: { search: query, per_page: DEFAULT_PER_PAGE, ...options, }, }); }, createBranch(id, { ref, branch }) { const url = Api.buildUrl(this.createBranchPath).replace(':id', encodeURIComponent(id)); return axios.post(url, { ref, branch, }); }, /** * @deprecated This method will be removed soon. Use the * `updateUserStatus` method in `~/rest_api` instead. */ postUserStatus({ emoji, message, availability }) { const url = Api.buildUrl(this.userPostStatusPath); return axios.put(url, { emoji, message, availability, }); }, postMergeRequestPipeline(id, { mergeRequestId }) { const url = Api.buildUrl(this.mergeRequestsPipeline) .replace(':id', encodeURIComponent(id)) .replace(':merge_request_iid', mergeRequestId); return axios.post(url); }, releases(id, options = {}) { const url = Api.buildUrl(this.releasesPath).replace(':id', encodeURIComponent(id)); return axios.get(url, { params: { per_page: DEFAULT_PER_PAGE, ...options, }, }); }, release(projectPath, tagName) { const url = Api.buildUrl(this.releasePath) .replace(':id', encodeURIComponent(projectPath)) .replace(':tag_name', encodeURIComponent(tagName)); return axios.get(url); }, createRelease(projectPath, release) { const url = Api.buildUrl(this.releasesPath).replace(':id', encodeURIComponent(projectPath)); return axios.post(url, release); }, updateRelease(projectPath, tagName, release) { const url = Api.buildUrl(this.releasePath) .replace(':id', encodeURIComponent(projectPath)) .replace(':tag_name', encodeURIComponent(tagName)); return axios.put(url, release); }, createReleaseLink(projectPath, tagName, link) { const url = Api.buildUrl(this.releaseLinksPath) .replace(':id', encodeURIComponent(projectPath)) .replace(':tag_name', encodeURIComponent(tagName)); return axios.post(url, link); }, deleteReleaseLink(projectPath, tagName, linkId) { const url = Api.buildUrl(this.releaseLinkPath) .replace(':id', encodeURIComponent(projectPath)) .replace(':tag_name', encodeURIComponent(tagName)) .replace(':link_id', encodeURIComponent(linkId)); return axios.delete(url); }, adminStatistics() { const url = Api.buildUrl(this.adminStatisticsPath); return axios.get(url); }, pipelineSingle(id, pipelineId) { const url = Api.buildUrl(this.pipelineSinglePath) .replace(':id', encodeURIComponent(id)) .replace(':pipeline_id', encodeURIComponent(pipelineId)); return axios.get(url); }, pipelineJobs(projectId, pipelineId, params) { const url = Api.buildUrl(this.pipelineJobsPath) .replace(':id', encodeURIComponent(projectId)) .replace(':pipeline_id', encodeURIComponent(pipelineId)); return axios.get(url, { params }); }, // Return all pipelines for a project or filter by query params pipelines(id, options = {}) { const url = Api.buildUrl(this.pipelinesPath).replace(':id', encodeURIComponent(id)); return axios.get(url, { params: options, }); }, createPipeline(id, data) { const url = Api.buildUrl(this.createPipelinePath).replace(':id', encodeURIComponent(id)); return axios.post(url, data, { headers: { 'Content-Type': 'application/json', }, }); }, environments(id) { const url = Api.buildUrl(this.environmentsPath).replace(':id', encodeURIComponent(id)); return axios.get(url); }, createContextCommits(id, mergeRequestIid, data) { const url = Api.buildUrl(this.contextCommitsPath) .replace(':id', encodeURIComponent(id)) .replace(':merge_request_iid', mergeRequestIid); return axios.post(url, data); }, allContextCommits(id, mergeRequestIid) { const url = Api.buildUrl(this.contextCommitsPath) .replace(':id', encodeURIComponent(id)) .replace(':merge_request_iid', mergeRequestIid); return axios.get(url); }, removeContextCommits(id, mergeRequestIid, data) { const url = Api.buildUrl(this.contextCommitsPath) .replace(':id', id) .replace(':merge_request_iid', mergeRequestIid); return axios.delete(url, { data }); }, getRawFile(id, path, params = {}) { const url = Api.buildUrl(this.rawFilePath) .replace(':id', encodeURIComponent(id)) .replace(':path', encodeURIComponent(path)); return axios.get(url, { params }); }, updateIssue(project, issue, data = {}) { const url = Api.buildUrl(Api.issuePath) .replace(':id', encodeURIComponent(project)) .replace(':issue_iid', encodeURIComponent(issue)); return axios.put(url, data); }, updateMergeRequest(project, mergeRequest, data = {}) { const url = Api.buildUrl(Api.projectMergeRequestPath) .replace(':id', encodeURIComponent(project)) .replace(':mrid', encodeURIComponent(mergeRequest)); return axios.put(url, data); }, tags(id, query = '', options = {}) { const url = Api.buildUrl(this.tagsPath).replace(':id', encodeURIComponent(id)); return axios.get(url, { params: { search: query, per_page: DEFAULT_PER_PAGE, ...options, }, }); }, freezePeriods(id) { const url = Api.buildUrl(this.freezePeriodsPath).replace(':id', encodeURIComponent(id)); return axios.get(url); }, createFreezePeriod(id, freezePeriod = {}) { const url = Api.buildUrl(this.freezePeriodsPath).replace(':id', encodeURIComponent(id)); return axios.post(url, freezePeriod); }, updateFreezePeriod(id, freezePeriod = {}) { const url = Api.buildUrl(this.freezePeriodPath) .replace(':id', encodeURIComponent(id)) .replace(':freeze_period_id', encodeURIComponent(freezePeriod.id)); return axios.put(url, freezePeriod); }, deleteFreezePeriod(id, freezePeriodId) { const url = Api.buildUrl(this.freezePeriodPath) .replace(':id', encodeURIComponent(id)) .replace(':freeze_period_id', encodeURIComponent(freezePeriodId)); return axios.delete(url); }, trackRedisCounterEvent(event) { if (!gon.features?.usageDataApi) { return null; } const url = Api.buildUrl(this.serviceDataIncrementCounterPath); const headers = { 'Content-Type': 'application/json', }; return axios.post(url, { event }, { headers }); }, trackRedisHllUserEvent(event) { if (!gon.current_user_id || !gon.features?.usageDataApi) { return null; } const url = Api.buildUrl(this.serviceDataIncrementUniqueUsersPath); const headers = { 'Content-Type': 'application/json', }; return axios.post(url, { event }, { headers }); }, buildUrl(url) { return joinPaths(gon.relative_url_root || '', url.replace(':version', gon.api_version)); }, fetchFeatureFlagUserLists(id, page) { const url = Api.buildUrl(this.featureFlagUserLists).replace(':id', id); return axios.get(url, { params: { page } }); }, searchFeatureFlagUserLists(id, search) { const url = Api.buildUrl(this.featureFlagUserLists).replace(':id', id); return axios.get(url, { params: { search } }); }, createFeatureFlagUserList(id, list) { const url = Api.buildUrl(this.featureFlagUserLists).replace(':id', id); return axios.post(url, list); }, fetchFeatureFlagUserList(id, listIid) { const url = Api.buildUrl(this.featureFlagUserList) .replace(':id', id) .replace(':list_iid', listIid); return axios.get(url); }, updateFeatureFlagUserList(id, list) { const url = Api.buildUrl(this.featureFlagUserList) .replace(':id', id) .replace(':list_iid', list.iid); return axios.put(url, list); }, deleteFeatureFlagUserList(id, listIid) { const url = Api.buildUrl(this.featureFlagUserList) .replace(':id', id) .replace(':list_iid', listIid); return axios.delete(url); }, deployKeys(params = {}) { const url = Api.buildUrl(this.deployKeysPath); return axios.get(url, { params: { per_page: DEFAULT_PER_PAGE, ...params } }); }, // TODO: replace this when GraphQL support has been added https://gitlab.com/gitlab-org/gitlab/-/issues/352184 projectSecureFiles(projectId, options = {}) { const url = Api.buildUrl(this.secureFilesPath).replace(':project_id', projectId); return axios.get(url, { params: { per_page: DEFAULT_PER_PAGE, ...options } }); }, async updateNotificationSettings(projectId, groupId, data = {}) { let url = Api.buildUrl(this.notificationSettingsPath); if (projectId) { url = Api.buildUrl(this.projectNotificationSettingsPath).replace(':id', projectId); } else if (groupId) { url = Api.buildUrl(this.groupNotificationSettingsPath).replace(':id', groupId); } const result = await axios.put(url, data); return result; }, async getNotificationSettings(projectId, groupId) { let url = Api.buildUrl(this.notificationSettingsPath); if (projectId) { url = Api.buildUrl(this.projectNotificationSettingsPath).replace(':id', projectId); } else if (groupId) { url = Api.buildUrl(this.groupNotificationSettingsPath).replace(':id', groupId); } const result = await axios.get(url); return result; }, deleteDependencyProxyCacheList(groupId, options = {}) { const url = Api.buildUrl(this.dependencyProxyPath).replace(':id', groupId); return axios.delete(url, { params: { ...options } }); }, }; export default Api;