All files / lib/codecs corejson.js

100% Statements 73/73
90.24% Branches 37/41
100% Functions 9/9
100% Lines 73/73
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 1256x 6x     6x 1x   5x       52x 52x 10x   42x       2x 2x 1x   1x       6x 6x 1x   5x       7x 7x 2x   5x       6x 6x 6x 13x 6x 6x 6x     6x       20x   20x   6x 6x 6x 6x 6x 6x 6x 14x   7x 7x 7x 7x 7x 7x 7x 7x 2x 2x 2x 2x 2x 2x 2x   7x 7x   2x 2x 2x 2x     2x 5x   1x 1x 1x   1x     4x         6x       11x 11x 11x   11x       6x      
const document = require('../document')
const URL = require('url-parse')
 
function unescapeKey (key) {
  if (key.match(/__(type|meta)$/)) {
    return key.substring(1)
  }
  return key
}
 
function getString (obj, key) {
  const value = obj[key]
  if (typeof (value) === 'string') {
    return value
  }
  return ''
}
 
function getBoolean (obj, key) {
  const value = obj[key]
  if (typeof (value) === 'boolean') {
    return value
  }
  return false
}
 
function getObject (obj, key) {
  const value = obj[key]
  if (typeof (value) === 'object') {
    return value
  }
  return {}
}
 
function getArray (obj, key) {
  const value = obj[key]
  if (value instanceof Array) {
    return value
  }
  return []
}
 
function getContent (data, baseUrl) {
  const excluded = ['_type', '_meta']
  var content = {}
  for (var property in data) {
    if (data.hasOwnProperty(property) && !excluded.includes(property)) {
      const key = unescapeKey(property)
      const value = primitiveToNode(data[property], baseUrl)
      content[key] = value
    }
  }
  return content
}
 
function primitiveToNode (data, baseUrl) {
  const isObject = data instanceof Object && !(data instanceof Array)
 
  if (isObject && data._type === 'document') {
    // Document
    const meta = getObject(data, '_meta')
    const relativeUrl = getString(meta, 'url')
    const url = relativeUrl ? URL(relativeUrl, baseUrl).toString() : ''
    const title = getString(meta, 'title')
    const description = getString(meta, 'description')
    const content = getContent(data, url)
    return new document.Document(url, title, description, content)
  } else if (isObject && data._type === 'link') {
    // Link
    const relativeUrl = getString(data, 'url')
    const url = relativeUrl ? URL(relativeUrl, baseUrl).toString() : ''
    const method = getString(data, 'action') || 'get'
    const title = getString(data, 'title')
    const description = getString(data, 'description')
    const fieldsData = getArray(data, 'fields')
    var fields = []
    for (let idx = 0, len = fieldsData.length; idx < len; idx++) {
      let value = fieldsData[idx]
      let name = getString(value, 'name')
      let required = getBoolean(value, 'required')
      let location = getString(value, 'location')
      let fieldDescription = getString(value, 'fieldDescription')
      let field = new document.Field(name, required, location, fieldDescription)
      fields.push(field)
    }
    return new document.Link(url, method, 'application/json', fields, title, description)
  } else if (isObject) {
    // Object
    let content = {}
    for (let key in data) {
      Eif (data.hasOwnProperty(key)) {
        content[key] = primitiveToNode(data[key], baseUrl)
      }
    }
    return content
  } else if (data instanceof Array) {
    // Object
    let content = []
    for (let idx = 0, len = data.length; idx < len; idx++) {
      content.push(primitiveToNode(data[idx], baseUrl))
    }
    return content
  }
  // Primitive
  return data
}
 
class CoreJSONCodec {
  constructor () {
    this.mediaType = 'application/coreapi+json'
  }
 
  decode (text, options = {}) {
    let data = text
    Eif (options.preloaded === undefined || !options.preloaded) {
      data = JSON.parse(text)
    }
    return primitiveToNode(data, options.url)
  }
}
 
module.exports = {
  CoreJSONCodec: CoreJSONCodec
}