Use graphql-markdown package

This commit is contained in:
Brian Beck 2017-03-18 14:54:22 -07:00
parent 593ac5a01f
commit 1c8d6c4765
3 changed files with 36 additions and 165 deletions

View file

@ -20,7 +20,7 @@
"build:docs": "npm run build:docs:readme && npm run build:docs:schema && npm run build:docs:types",
"build:docs:readme": "doctoc --title \"## Contents\" README.md",
"build:docs:schema": "printf '# GraphQL Schema\\n\\n%s\n' \"$(npm run -s print-schema:md)\" > docs/schema.md",
"build:docs:types": "babel-node scripts/render-types.js > docs/types.md",
"build:docs:types": "graphql-markdown --prologue 'You may also be interested in reading the [schema in GraphQL syntax](schema.md).' ./schema.json > docs/types.md",
"build:lib": "babel --out-dir lib src",
"clean": "npm run clean:lib",
"clean:lib": "rm -rf lib",
@ -91,6 +91,7 @@
"coveralls": "^2.11.15",
"cross-env": "^3.1.3",
"doctoc": "^1.2.0",
"graphql-markdown": "^1.0.0",
"marked": "^0.3.6",
"nodemon": "^1.11.0",
"nyc": "^10.0.0",

View file

@ -1,162 +0,0 @@
import marked from 'marked'
const schema = require('../schema.json').__schema
// Ideally, we could just spit out the existing description Markdown everywhere
// and leave it to be rendered by whatever processes the output. But some
// Markdown renderers, including GitHub's, don't process Markdown if it's within
// an HTML tag. So in some places (like descriptions of the types themselves) we
// just output the raw description. In other places, like table cells, we need
// to output pre-rendered Markdown, otherwise GitHub won't interpret it.
marked.setOptions({
breaks: false
})
function markdown (markup) {
return marked(markup || '')
.replace(/<\/p>\s*<p>/g, '<br><br>')
.replace(/<\/?p>/g, '')
.trim()
}
function sortBy (arr, property) {
arr.sort((a, b) => {
const aValue = a[property]
const bValue = b[property]
if (aValue > bValue) return 1
if (bValue > aValue) return -1
return 0
})
}
function renderType (type) {
if (type.kind === 'NON_NULL') {
return renderType(type.ofType) + '!'
}
if (type.kind === 'LIST') {
return `[${renderType(type.ofType)}]`
}
return `[${type.name}](#${type.name.toLowerCase()})`
}
function renderObject (type, { skipTitle = false } = {}) {
if (!skipTitle) {
console.log(`\n### ${type.name}\n`)
}
if (type.description) {
console.log(`${type.description}\n`)
}
console.log('<table><thead>')
console.log(' <tr>')
console.log(' <th align="left">Field</th>')
console.log(' <th align="right">Argument</th>')
console.log(' <th align="left">Type</th>')
console.log(' <th align="left">Description</th>')
console.log(' </tr>')
console.log('</thead><tbody>')
type.fields.forEach(field => {
console.log(' <tr>')
console.log(` <td colspan="2" valign="top"><strong>${field.name}</strong>${field.isDeprecated ? ' ⚠️' : ''}</td>`)
console.log(` <td valign="top">${markdown(renderType(field.type))}</td>`)
console.log(` <td>`)
if (field.description) {
console.log(markdown(field.description))
}
if (field.isDeprecated) {
console.log(' <br/><br/><p>⚠️ <strong>DEPRECATED</strong></p>')
console.log(` <blockquote>${markdown(field.deprecationReason)}</blockquote>`)
}
console.log(' </td>')
console.log(' </tr>')
if (field.args.length) {
field.args.forEach((arg, i) => {
console.log(' <tr>')
console.log(` <td colspan="2" align="right" valign="top">${arg.name}</td>`)
console.log(` <td valign="top">${markdown(renderType(arg.type))}</td>`)
console.log(` <td>${markdown(arg.description)}</td>`)
console.log(' </tr>')
})
}
})
console.log('</tbody></table>')
}
const types = schema.types.filter(type => !type.name.startsWith('__'))
const query = types.filter(type => type.name === schema.queryType.name)[0]
const objects = types.filter(type => type.kind === 'OBJECT' && type !== query)
const enums = types.filter(type => type.kind === 'ENUM').sort()
const scalars = types.filter(type => type.kind === 'SCALAR').sort()
const interfaces = types.filter(type => type.kind === 'INTERFACE').sort()
sortBy(objects, 'name')
sortBy(enums, 'name')
sortBy(scalars, 'name')
sortBy(interfaces, 'name')
console.log('# Schema Types\n')
console.log('You may also be interested in reading the [schema in GraphQL syntax](schema.md).\n')
console.log('<details>')
console.log(' <summary><strong>Table of Contents</strong></summary>\n')
console.log(' * [Query](#query)')
console.log(' * [Objects](#objects)')
objects.forEach(type => {
console.log(` * [${type.name}](#${type.name.toLowerCase()})`)
})
console.log(' * [Enums](#enums)')
enums.forEach(type => {
console.log(` * [${type.name}](#${type.name.toLowerCase()})`)
})
console.log(' * [Scalars](#scalars)')
scalars.forEach(type => {
console.log(` * [${type.name}](#${type.name.toLowerCase()})`)
})
console.log(' * [Interfaces](#interfaces)')
interfaces.forEach(type => {
console.log(` * [${type.name}](#${type.name.toLowerCase()})`)
})
console.log('\n</details>')
console.log(`\n## Query ${query.name === 'Query' ? '' : '(' + query.name + ')'}`)
renderObject(query, { skipTitle: true })
console.log('\n## Objects')
objects.forEach(type => renderObject(type))
console.log('\n## Enums')
enums.forEach(type => {
console.log(`\n### ${type.name}\n`)
if (type.description) {
console.log(`${type.description}\n`)
}
console.log('<table><thead>')
console.log(' <th align="left">Value</th>')
console.log(' <th align="left">Description</th>')
console.log('</thead><tbody>')
type.enumValues.forEach(value => {
console.log(' <tr>')
console.log(` <td valign="top"><strong>${value.name}</strong>${value.isDeprecated ? ' ⚠️' : ''}</td>`)
console.log(' <td>')
if (value.description) {
console.log(markdown(value.description))
}
if (value.isDeprecated) {
console.log(' <br/><br/><p>⚠️ <strong>DEPRECATED</strong></p>')
console.log(` <blockquote>${markdown(value.deprecationReason)}</blockquote>`)
}
console.log(' </td>')
console.log(' </tr>')
})
console.log('</tbody></table>')
})
console.log('\n## Scalars\n')
scalars.forEach(type => {
console.log(`### ${type.name}\n`)
if (type.description) {
console.log(`${type.description}\n`)
}
})
console.log('\n## Interfaces\n')
interfaces.forEach(type => renderObject(type))

View file

@ -1594,6 +1594,12 @@ encodeurl@~1.0.1:
version "1.0.1"
resolved "https://registry.yarnpkg.com/encodeurl/-/encodeurl-1.0.1.tgz#79e3d58655346909fe6f0f45a5de68103b294d20"
encoding@^0.1.11:
version "0.1.12"
resolved "https://registry.yarnpkg.com/encoding/-/encoding-0.1.12.tgz#538b66f3ee62cd1ab51ec323829d1f9480c74beb"
dependencies:
iconv-lite "~0.4.13"
end-of-stream@1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/end-of-stream/-/end-of-stream-1.0.0.tgz#d4596e702734a93e40e9af864319eabd99ff2f0e"
@ -2231,6 +2237,15 @@ graceful-fs@^4.1.2, graceful-fs@^4.1.4:
version "1.0.1"
resolved "https://registry.yarnpkg.com/graceful-readlink/-/graceful-readlink-1.0.1.tgz#4cafad76bc62f02fa039b2f94e9a3dd3a391a725"
graphql-markdown@^1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/graphql-markdown/-/graphql-markdown-1.0.0.tgz#b540ccabdadf75e54e1c28f7687eef6cd6cedf5b"
dependencies:
graphql "^0.9.1"
marked "^0.3.6"
minimist "^1.2.0"
node-fetch "^1.6.3"
graphql-relay@^0.4.4:
version "0.4.4"
resolved "https://registry.yarnpkg.com/graphql-relay/-/graphql-relay-0.4.4.tgz#876a654445b6af4539f81cb9befd5cd7ead129dd"
@ -2241,6 +2256,12 @@ graphql@^0.8.2:
dependencies:
iterall "1.0.2"
graphql@^0.9.1:
version "0.9.1"
resolved "https://registry.yarnpkg.com/graphql/-/graphql-0.9.1.tgz#f4d154cbec054d4a5d3b1be95f23435c09aa86c8"
dependencies:
iterall "1.0.3"
handlebars@^4.0.3:
version "4.0.6"
resolved "https://registry.yarnpkg.com/handlebars/-/handlebars-4.0.6.tgz#2ce4484850537f9c97a8026d5399b935c4ed4ed7"
@ -2338,7 +2359,7 @@ http-signature@~1.1.0:
jsprim "^1.2.2"
sshpk "^1.7.0"
iconv-lite@0.4.13:
iconv-lite@0.4.13, iconv-lite@~0.4.13:
version "0.4.13"
resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.4.13.tgz#1f88aba4ab0b1508e8312acc39345f36e992e2f2"
@ -2595,7 +2616,7 @@ is-retry-allowed@^1.0.0:
version "1.1.0"
resolved "https://registry.yarnpkg.com/is-retry-allowed/-/is-retry-allowed-1.1.0.tgz#11a060568b67339444033d0125a61a20d564fb34"
is-stream@^1.0.0:
is-stream@^1.0.0, is-stream@^1.0.1:
version "1.1.0"
resolved "https://registry.yarnpkg.com/is-stream/-/is-stream-1.1.0.tgz#12d4a3dd4e68e0b79ceb8dbc84173ae80d91ca44"
@ -2685,6 +2706,10 @@ iterall@1.0.2:
version "1.0.2"
resolved "https://registry.yarnpkg.com/iterall/-/iterall-1.0.2.tgz#41a2e96ce9eda5e61c767ee5dc312373bb046e91"
iterall@1.0.3:
version "1.0.3"
resolved "https://registry.yarnpkg.com/iterall/-/iterall-1.0.3.tgz#e0b31958f835013c323ff0b10943829ac69aa4b7"
jodid25519@^1.0.0:
version "1.0.2"
resolved "https://registry.yarnpkg.com/jodid25519/-/jodid25519-1.0.2.tgz#06d4912255093419477d425633606e0e90782967"
@ -3134,6 +3159,13 @@ nested-error-stacks@^1.0.0:
dependencies:
inherits "~2.0.1"
node-fetch@^1.6.3:
version "1.6.3"
resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-1.6.3.tgz#dc234edd6489982d58e8f0db4f695029abcd8c04"
dependencies:
encoding "^0.1.11"
is-stream "^1.0.1"
node-pre-gyp@^0.6.29:
version "0.6.32"
resolved "https://registry.yarnpkg.com/node-pre-gyp/-/node-pre-gyp-0.6.32.tgz#fc452b376e7319b3d255f5f34853ef6fd8fe1fd5"