All files / features/parses-json-array-and-object-data-response parse-json-response.js

91.48% Statements 86/94
82.35% Branches 14/17
80% Functions 4/5
91.48% Lines 86/94

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 952x 2x 2x 2x 2x 2x 2x 2x 2x 2x 1x 9x     9x 9x 9x 2x 2x 2x 2x 2x 2x 2x 7x 7x 7x 7x 7x 1x 1x 1x 1x 1x 1x 1x 7x 1x 1x 1x 1x 1x 1x 5x 5x 5x 5x 5x 5x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 1x 1x 1x 1x 1x 1x 1x 2x             1x 1x 1x 1x 1x 1x 2x 2x 2x 2x 2x 2x 2x 2x 2x 18x 18x  
import { linkHeaderOf, parseHasMoreHeader } from '../../utils/response.js'
/** @import {ParsedResponse} from '../data-loading/fetch-data' */
 
/**
 * Checks if response is a valid CSV response
 * It checks by checking content type is CSV
 *
 * @param {Response} response - response from fetch
 * @returns {Promise<ParsedResponse>} parsed response
 */
export async function parseJsonResponse (response) {
  if (!isJsonResponse(response)) {
    throw Error('Not an JSON response')
  }
  const json = await response.json()
  return Array.isArray(json) ? parseJsonArrayResponse(json, response) : parseJsonObjectResponse(json, response)
}
 
/**
 *
 * @param {any[]} json - json array parsed from `response` body
 * @param {Response} response - response from fetch
 * @returns {ParsedResponse} parsed response
 */
function parseJsonArrayResponse (json, response) {
  const linkHeader = linkHeaderOf(response)
  const hasMoreHeader = parseHasMoreHeader(response)
  const data = json
  if (linkHeader.byRel.next) {
    return {
      hasMore: true,
      navigationMode: 'link',
      href: linkHeader.byRel.next[0].url,
      data,
    }
  }
  if (hasMoreHeader) {
    return {
      hasMore: true,
      navigationMode: 'after_value',
      data,
    }
  }
 
  return {
    hasMore: false,
    data,
  }
}
 
/**
 *
 * @param {any} json - json object parsed from `response` body
 * @param {Response} response - response from fetch
 * @returns {ParsedResponse} parsed response
 */
function parseJsonObjectResponse (json, response) {
  const { links, hasMore, records } = json
  const data = records
  const nextLink = typeof links?.next === 'string' ? links.next : linkHeaderOf(response).byRel.next?.[0]?.url
  const useHasMore = hasMore ?? parseHasMoreHeader(response)
 
  if (nextLink) {
    return {
      hasMore: true,
      navigationMode: 'link',
      href: nextLink,
      data,
    }
  }
  if (useHasMore) {
    return {
      hasMore: true,
      navigationMode: 'after_value',
      data,
    }
  }
 
  return {
    hasMore: false,
    data,
  }
}
 
/**
 * Checks if response is a valid CSV response
 * It checks by checking content type is CSV and the response is a 200 status ok
 *
 * @param {Response} response - response from fetch
 * @returns {boolean} true if is a valid CSV response, false otherwise
 */
export function isJsonResponse (response) {
  return response.ok && response.headers.get('Content-Type') === 'application/json'
}