function joiKeysToMD({
  keys,
  mdString = ``,
  level = 1,
  parent = null,
  parentMetas = [],
}) {
  if (
    !keys ||
    (parentMetas.length && parentMetas.find(meta => meta.portableOptions))
  ) {
    return mdString
  }

  Object.entries(keys).forEach(([key, value]) => {
    const isRequired = value.flags && value.flags.presence === `required`

    const title = `${parent ? `${parent}.` : ``}${key}${
      isRequired ? ` (**required**)` : ``
    }`

    mdString += `${`#`.repeat(level + 1)} ${title}`

    if (value.description) {
      mdString += `\n\n`
      const description = value.description.trim()
      mdString += description.endsWith(`.`) ? description : `${description}.`
    }

    if (value.type) {
      const { trueType } =
        (value.meta && value.meta.find(meta => `trueType` in meta)) || {}

      mdString += `\n\n`
      mdString += `**Field type**: \`${(trueType || value.type)
        .split(`|`)
        .map(typename => _.startCase(typename))
        .join(` | `)}\``
    }

    if (
      (value.flags && `default` in value.flags) ||
      (value.meta && value.meta.find(meta => `default` in meta))
    ) {
      const defaultValue =
        ((value.meta && value.meta.find(meta => `default` in meta)) || {})
          .default || value.flags.default

      let printedValue

      if (typeof defaultValue === `string`) {
        printedValue = defaultValue
      } else if (Array.isArray(defaultValue)) {
        printedValue = `[${defaultValue.join(`, `)}]`
      } else if (
        [`boolean`, `function`, `number`].includes(typeof defaultValue)
      ) {
        printedValue = defaultValue.toString()
      } else if (defaultValue === null) {
        printedValue = `null`
      }

      if (typeof printedValue === `string`) {
        mdString += `\n\n`
        mdString += `**Default value**: ${
          printedValue.includes(`\n`)
            ? `\n\`\`\`js\n${printedValue}\n\`\`\``
            : `\`${printedValue}\``
        }`
      }
    }

    if (value.meta) {
      const examples = value.meta.filter(meta => `example` in meta)
      examples.forEach(({ example }) => {
        mdString += `\n\n\`\`\`js\n` + example + `\n\`\`\`\n`
      })
    }

    mdString += `\n\n`

    const excludeChildren = excludeParentsChildren.includes(key)

    if (!excludeChildren && value.children) {
      mdString = joiKeysToMD({
        keys: value.children,
        mdString,
        level: level + 1,
        parent: title,
        parentMetas: value.meta,
      })
    }

    if (!excludeChildren && value.items && value.items.length) {
      value.items.forEach(item => {
        if (item.children) {
          mdString = joiKeysToMD({
            keys: item.children,
            mdString,
            level: level + 1,
            parent: title + `[]`,
            parentMetas: value.meta,
          })
        }
      })
    }
  })

  return mdString
}
Takes the keys from a Joi schema and recursively
turns the nested keys into structured markdown documentation

@param {object} keys
@param {string} mdString
@param {number} level
@param {string} parent