All files / app/assets/javascripts/graphql_shared utils.js

100% Statements 49/49
93.93% Branches 31/33
100% Functions 15/15
100% Lines 44/44

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165                    903x 12916x 7261x     5655x     903x 6731x 6731x                     903x 10341x 10341x 10341x                     903x 51x   43x 43x     903x                             903x 1586x 2x     1584x 2x     1582x 141x     1441x                         903x                   903x 3x 1x     3x                     903x 295x 1x     391x                     903x 44x     903x 201x 203x 200x   3x       201x 201x     903x 517x                      
import { isArray } from 'lodash';
import Visibility from 'visibilityjs';
 
/**
 * Ids generated by GraphQL endpoints are usually in the format
 * gid://gitlab/Environments/123. This method checks if the passed id follows that format
 *
 * @param {String|Number} id The id value
 * @returns {Boolean}
 */
export const isGid = (id) => {
  if (typeof id === 'string' && id.startsWith('gid://gitlab/')) {
    return true;
  }
 
  return false;
};
 
const parseGid = (gid) => {
  const [type, id] = `${gid}`.replace(/gid:\/\/gitlab\//g, '').split('/');
  return { type, id };
};
 
/**
 * Ids generated by GraphQL endpoints are usually in the format
 * gid://gitlab/Environments/123. This method extracts Id number
 * from the Id path
 *
 * @param {String} gid GraphQL global ID
 * @returns {Number}
 */
export const getIdFromGraphQLId = (gid = '') => {
  const rawId = isGid(gid) ? parseGid(gid).id : gid;
  const id = parseInt(rawId, 10);
  return Number.isInteger(id) ? id : null;
};
 
/**
 * Ids generated by GraphQL endpoints are usually in the format
 * gid://gitlab/Environments/123. This method extracts Type string
 * from the Id path
 *
 * @param {String} gid GraphQL global ID
 * @returns {String}
 */
export const getTypeFromGraphQLId = (gid = '') => {
  if (!isGid(gid)) return null;
 
  const { type } = parseGid(gid);
  return type || null;
};
 
export const mutationOperationMode = {
  append: 'APPEND',
  remove: 'REMOVE',
  replace: 'REPLACE',
};
 
/**
 * Ids generated by GraphQL endpoints are usually in the format
 * gid://gitlab/Groups/123. This method takes a type and an id
 * and interpolates the 2 values into the expected GraphQL ID format.
 *
 * @param {String} type The entity type
 * @param {String|Number} id The id value
 * @returns {String}
 */
export const convertToGraphQLId = (type, id) => {
  if (typeof type !== 'string') {
    throw new TypeError(`type must be a string; got ${typeof type}`);
  }
 
  if (!['number', 'string'].includes(typeof id)) {
    throw new TypeError(`id must be a number or string; got ${typeof id}`);
  }
 
  if (isGid(id)) {
    return id;
  }
 
  return `gid://gitlab/${type}/${id}`;
};
 
/**
 * Ids generated by GraphQL endpoints are usually in the format
 * gid://gitlab/Groups/123. This method takes a type and an
 * array of ids and tranforms the array values into the expected
 * GraphQL ID format.
 *
 * @param {String} type The entity type
 * @param {Array} ids An array of id values
 * @returns {Array}
 */
export const convertToGraphQLIds = (type, ids) => ids.map((id) => convertToGraphQLId(type, id));
 
/**
 * Ids generated by GraphQL endpoints are usually in the format
 * gid://gitlab/Groups/123. This method takes an array of
 * GraphQL Ids and converts them to a number.
 *
 * @param {Array} ids An array of GraphQL IDs
 * @returns {Array}
 */
export const convertFromGraphQLIds = (ids) => {
  if (!isArray(ids)) {
    throw new TypeError(`ids must be an array; got ${typeof ids}`);
  }
 
  return ids.map((id) => getIdFromGraphQLId(id));
};
 
/**
 * Ids generated by GraphQL endpoints are usually in the format
 * gid://gitlab/Groups/123. This method takes an array of nodes
 * and converts the `id` properties from a GraphQL Id to a number.
 *
 * @param {Array} nodes An array of nodes with an `id` property
 * @returns {Array}
 */
export const convertNodeIdsFromGraphQLIds = (nodes) => {
  if (!isArray(nodes)) {
    throw new TypeError(`nodes must be an array; got ${typeof nodes}`);
  }
 
  return nodes.map((node) => (node.id ? { ...node, id: getIdFromGraphQLId(node.id) } : node));
};
 
/**
 * This function takes a GraphQL query data as a required argument and
 * the field name to resolve as an optional argument
 * and returns resolved field's data or an empty array
 * @param {Object} queryData
 * @param {String} nodesField (in most cases it will be 'nodes')
 * @returns {Array}
 */
export const getNodesOrDefault = (queryData, nodesField = 'nodes') => {
  return queryData?.[nodesField] ?? [];
};
 
export const toggleQueryPollingByVisibility = (queryRef, interval = 10000) => {
  const stopStartQuery = (query) => {
    if (!Visibility.hidden()) {
      query.startPolling(interval);
    } else {
      query.stopPolling();
    }
  };
 
  stopStartQuery(queryRef);
  Visibility.change(stopStartQuery.bind(null, queryRef));
};
 
export const etagQueryHeaders = (featureCorrelation, etagResource = '') => {
  return {
    fetchOptions: {
      method: 'GET',
    },
    headers: {
      'X-GITLAB-GRAPHQL-FEATURE-CORRELATION': featureCorrelation,
      'X-GITLAB-GRAPHQL-RESOURCE-ETAG': etagResource,
      'X-Requested-With': 'XMLHttpRequest',
    },
  };
};