import { pick } from 'lodash'; import createGqClient, { fetchPolicies } from '~/lib/graphql'; import { truncateSha } from '~/lib/utils/text_utility'; import { convertObjectPropsToCamelCase, convertObjectPropsToSnakeCase, } from '~/lib/utils/common_utils'; /** * Converts a release object into a JSON object that can sent to the public * API to create or update a release. * @param {Object} release The release object to convert * @param {string} createFrom The ref to create a new tag from, if necessary */ export const releaseToApiJson = (release, createFrom = null) => { const name = release.name?.trim().length > 0 ? release.name.trim() : null; // Milestones may be either a list of milestone objects OR just a list // of milestone titles. The API requires only the titles be sent. const milestones = (release.milestones || []).map((m) => m.title || m); return convertObjectPropsToSnakeCase( { name, tagName: release.tagName, ref: createFrom, description: release.description, milestones, assets: release.assets, }, { deep: true }, ); }; /** * Converts a JSON release object returned by the Release API * into the structure this Vue application can work with. * @param {Object} json The JSON object received from the release API */ export const apiJsonToRelease = (json) => { const release = convertObjectPropsToCamelCase(json, { deep: true }); release.milestones = release.milestones || []; return release; }; export const gqClient = createGqClient({}, { fetchPolicy: fetchPolicies.NO_CACHE }); const convertScalarProperties = (graphQLRelease) => pick(graphQLRelease, [ 'name', 'tagName', 'tagPath', 'descriptionHtml', 'releasedAt', 'upcomingRelease', ]); const convertAssets = (graphQLRelease) => ({ assets: { count: graphQLRelease.assets.count, sources: [...graphQLRelease.assets.sources.nodes], links: graphQLRelease.assets.links.nodes.map((l) => ({ ...l, linkType: l.linkType?.toLowerCase(), })), }, }); const convertEvidences = (graphQLRelease) => ({ evidences: graphQLRelease.evidences.nodes.map((e) => e), }); const convertLinks = (graphQLRelease) => ({ _links: { ...graphQLRelease.links, self: graphQLRelease.links?.selfUrl, }, }); const convertCommit = (graphQLRelease) => { if (!graphQLRelease.commit) { return {}; } return { commit: { shortId: truncateSha(graphQLRelease.commit.sha), title: graphQLRelease.commit.title, }, commitPath: graphQLRelease.commit.webUrl, }; }; const convertAuthor = (graphQLRelease) => ({ author: graphQLRelease.author }); const convertMilestones = (graphQLRelease) => ({ milestones: graphQLRelease.milestones.nodes.map((m) => ({ ...m, webUrl: m.webPath, webPath: undefined, issueStats: { total: m.stats.totalIssuesCount, closed: m.stats.closedIssuesCount, }, stats: undefined, })), }); /** * Converts a single release object fetched from GraphQL * into a release object that matches the shape of the REST API * (the same shape that is returned by `apiJsonToRelease` above.) * * @param graphQLRelease The release object returned from a GraphQL query */ export const convertGraphQLRelease = (graphQLRelease) => ({ ...convertScalarProperties(graphQLRelease), ...convertAssets(graphQLRelease), ...convertEvidences(graphQLRelease), ...convertLinks(graphQLRelease), ...convertCommit(graphQLRelease), ...convertAuthor(graphQLRelease), ...convertMilestones(graphQLRelease), }); /** * Converts the response from all_releases.query.graphql into the * same shape as is returned from the Releases REST API. * * This allows the release components to use the response * from either endpoint interchangeably. * * @param response The response received from the GraphQL endpoint */ export const convertAllReleasesGraphQLResponse = (response) => { const releases = response.data.project.releases.nodes.map(convertGraphQLRelease); const paginationInfo = { ...response.data.project.releases.pageInfo, }; return { data: releases, paginationInfo }; }; /** * Converts the response from one_release.query.graphql into the * same shape as is returned from the Releases REST API. * * This allows the release components to use the response * from either endpoint interchangeably. * * @param response The response received from the GraphQL endpoint */ export const convertOneReleaseGraphQLResponse = (response) => { const release = convertGraphQLRelease(response.data.project.release); return { data: release }; };