Add more argument descriptions, add new rendered type docs, move schema.md to doc dir

This commit is contained in:
Brian Beck 2016-11-28 19:14:43 -08:00
parent 8d73ed1233
commit 7c062ad3d8
8 changed files with 4112 additions and 34 deletions

View file

@ -283,7 +283,7 @@ agree, its ugly.
## Schema
See the [GraphQL schema][schema].
See the [GraphQL schema][schema] or the [rendered documentation][types].
[demo]: https://graphbrainz.herokuapp.com/
[Express]: http://expressjs.com/
@ -294,4 +294,5 @@ See the [GraphQL schema][schema].
[debug]: https://www.npmjs.com/package/debug
[GraphiQL]: https://github.com/graphql/graphiql
[Relay]: https://facebook.github.io/relay/
[schema]: schema.md
[schema]: doc/schema.md
[types]: doc/types.md

View file

@ -72,7 +72,16 @@ type Area implements Node, Entity {
places(after: String, first: Int): PlaceConnection
# A list of releases linked to this entity.
releases(after: String, first: Int, type: [ReleaseGroupType], status: [ReleaseStatus]): ReleaseConnection
releases(
after: String
first: Int
# Filter by one or more release group types.
type: [ReleaseGroupType]
# Filter by one or more release statuses.
status: [ReleaseStatus]
): ReleaseConnection
# Relationships between this entity and other entitites.
relationships: Relationships
@ -173,10 +182,25 @@ type Artist implements Node, Entity {
recordings(after: String, first: Int): RecordingConnection
# A list of releases linked to this entity.
releases(after: String, first: Int, type: [ReleaseGroupType], status: [ReleaseStatus]): ReleaseConnection
releases(
after: String
first: Int
# Filter by one or more release group types.
type: [ReleaseGroupType]
# Filter by one or more release statuses.
status: [ReleaseStatus]
): ReleaseConnection
# A list of release groups linked to this entity.
releaseGroups(after: String, first: Int, type: [ReleaseGroupType]): ReleaseGroupConnection
releaseGroups(
after: String
first: Int
# Filter by one or more release group types.
type: [ReleaseGroupType]
): ReleaseGroupConnection
# A list of works linked to this entity.
works(after: String, first: Int): WorkConnection
@ -616,7 +640,16 @@ type Label implements Node, Entity {
typeID: MBID
# A list of releases linked to this entity.
releases(after: String, first: Int, type: [ReleaseGroupType], status: [ReleaseStatus]): ReleaseConnection
releases(
after: String
first: Int
# Filter by one or more release group types.
type: [ReleaseGroupType]
# Filter by one or more release statuses.
status: [ReleaseStatus]
): ReleaseConnection
# Relationships between this entity and other entitites.
relationships: Relationships
@ -654,8 +687,13 @@ type LabelEdge {
# Fields indicating the begin and end date of an entitys
# lifetime, including whether it has ended (even if the date is unknown).
type LifeSpan {
# The start date of the entitys life span.
begin: Date
# The end date of the entitys life span.
end: Date
# Whether or not the entitys life span has ended.
ended: Boolean
}
@ -899,7 +937,16 @@ type Recording implements Node, Entity {
artists(after: String, first: Int): ArtistConnection
# A list of releases linked to this entity.
releases(after: String, first: Int, type: [ReleaseGroupType], status: [ReleaseStatus]): ReleaseConnection
releases(
after: String
first: Int
# Filter by one or more release group types.
type: [ReleaseGroupType]
# Filter by one or more release statuses.
status: [ReleaseStatus]
): ReleaseConnection
# Relationships between this entity and other entitites.
relationships: Relationships
@ -1296,7 +1343,13 @@ type Release implements Node, Entity {
recordings(after: String, first: Int): RecordingConnection
# A list of release groups linked to this entity.
releaseGroups(after: String, first: Int, type: [ReleaseGroupType]): ReleaseGroupConnection
releaseGroups(
after: String
first: Int
# Filter by one or more release group types.
type: [ReleaseGroupType]
): ReleaseGroupConnection
# Relationships between this entity and other entitites.
relationships: Relationships
@ -1391,7 +1444,16 @@ type ReleaseGroup implements Node, Entity {
artists(after: String, first: Int): ArtistConnection
# A list of releases linked to this entity.
releases(after: String, first: Int, type: [ReleaseGroupType], status: [ReleaseStatus]): ReleaseConnection
releases(
after: String
first: Int
# Filter by one or more release group types.
type: [ReleaseGroupType]
# Filter by one or more release statuses.
status: [ReleaseStatus]
): ReleaseConnection
# Relationships between this entity and other entitites.
relationships: Relationships

3850
doc/types.md Normal file

File diff suppressed because it is too large Load diff

View file

@ -17,7 +17,10 @@
},
"scripts": {
"build": "npm run build:lib && npm run update-schema && npm run build:docs",
"build:docs": "doctoc --title \"## Contents\" README.md",
"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' \"$(npm run -s print-schema:md)\" > doc/schema.md",
"build:docs:types": "babel-node scripts/render-types.js > doc/types.md",
"build:lib": "babel --out-dir lib src",
"clean": "npm run clean:lib",
"clean:lib": "rm -rf lib",
@ -31,9 +34,7 @@
"start": "node lib/index.js",
"start:dev": "nodemon --exec babel-node src/index.js",
"test": "mocha --compilers js:babel-register",
"update-schema": "npm run update-schema:json && npm run update-schema:md",
"update-schema:json": "npm run -s print-schema:json > schema.json",
"update-schema:md": "printf '# GraphQL Schema\\n\\n%s' \"$(npm run -s print-schema:md)\" > schema.md"
"update-schema": "npm run -s print-schema:json > schema.json"
},
"keywords": [
"musicbrainz",
@ -80,6 +81,7 @@
"babel-register": "^6.18.0",
"chai": "^3.5.0",
"doctoc": "^1.2.0",
"marked": "^0.3.6",
"mocha": "^3.2.0",
"nodemon": "^1.11.0",
"snazzy": "^5.0.0",

View file

@ -787,7 +787,7 @@
},
{
"name": "type",
"description": null,
"description": "Filter by one or more release group types.",
"type": {
"kind": "LIST",
"name": null,
@ -801,7 +801,7 @@
},
{
"name": "status",
"description": null,
"description": "Filter by one or more release statuses.",
"type": {
"kind": "LIST",
"name": null,
@ -1514,7 +1514,7 @@
},
{
"name": "type",
"description": null,
"description": "Filter by one or more release group types.",
"type": {
"kind": "LIST",
"name": null,
@ -1528,7 +1528,7 @@
},
{
"name": "status",
"description": null,
"description": "Filter by one or more release statuses.",
"type": {
"kind": "LIST",
"name": null,
@ -1575,7 +1575,7 @@
},
{
"name": "type",
"description": null,
"description": "Filter by one or more release group types.",
"type": {
"kind": "LIST",
"name": null,
@ -1698,7 +1698,7 @@
"fields": [
{
"name": "begin",
"description": null,
"description": "The start date of the entitys life span.",
"args": [],
"type": {
"kind": "SCALAR",
@ -1710,7 +1710,7 @@
},
{
"name": "end",
"description": null,
"description": "The end date of the entitys life span.",
"args": [],
"type": {
"kind": "SCALAR",
@ -1722,7 +1722,7 @@
},
{
"name": "ended",
"description": null,
"description": "Whether or not the entitys life span has ended.",
"args": [],
"type": {
"kind": "SCALAR",
@ -2030,7 +2030,7 @@
},
{
"name": "type",
"description": null,
"description": "Filter by one or more release group types.",
"type": {
"kind": "LIST",
"name": null,
@ -2044,7 +2044,7 @@
},
{
"name": "status",
"description": null,
"description": "Filter by one or more release statuses.",
"type": {
"kind": "LIST",
"name": null,
@ -2752,7 +2752,7 @@
},
{
"name": "type",
"description": null,
"description": "Filter by one or more release group types.",
"type": {
"kind": "LIST",
"name": null,
@ -3179,7 +3179,7 @@
},
{
"name": "type",
"description": null,
"description": "Filter by one or more release group types.",
"type": {
"kind": "LIST",
"name": null,
@ -3193,7 +3193,7 @@
},
{
"name": "status",
"description": null,
"description": "Filter by one or more release statuses.",
"type": {
"kind": "LIST",
"name": null,
@ -5029,7 +5029,7 @@
},
{
"name": "type",
"description": null,
"description": "Filter by one or more release group types.",
"type": {
"kind": "LIST",
"name": null,
@ -5043,7 +5043,7 @@
},
{
"name": "status",
"description": null,
"description": "Filter by one or more release statuses.",
"type": {
"kind": "LIST",
"name": null,

145
scripts/render-types.js Normal file
View file

@ -0,0 +1,145 @@
import marked from 'marked'
const schema = require('../schema.json').data.__schema
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}](#fixme)`
}
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(' <th>Field&nbsp;/&nbsp;Argument</th><th>Type</th><th>Description</th>')
console.log('</thead><tbody>')
type.fields.forEach(field => {
console.log(' <tr>')
console.log(` <td valign="top">**${field.name}**</td>`)
console.log(` <td valign="top">${renderType(field.type)}</td>`)
console.log(` <td>${markdown(field.description)}</td>`)
console.log(' </tr>')
if (field.args.length) {
field.args.forEach((arg, i) => {
console.log(' <tr>')
console.log(` <td align="right" valign="top">${arg.name}</td>`)
console.log(` <td valign="top">${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 the [schema in GraphQL syntax](schema.md).\n')
console.log('<details><summary>**Table of Contents**</summary><p><ul>')
console.log(' <li>[Query](#fixme)</li>')
console.log(' <li>[Objects](#fixme)<ul>')
objects.forEach(type => {
console.log(` <li>[${type.name}](#fixme)</li>`)
})
console.log(' </ul></li>')
console.log(' <li>[Enums](#fixme)<ul>')
enums.forEach(type => {
console.log(` <li>[${type.name}](#fixme)</li>`)
})
console.log(' </ul></li>')
console.log(' <li>[Scalars](#fixme)<ul>')
scalars.forEach(type => {
console.log(` <li>[${type.name}](#fixme)</li>`)
})
console.log(' </ul></li>')
console.log(' <li>[Interfaces](#fixme)<ul>')
interfaces.forEach(type => {
console.log(` <li>[${type.name}](#fixme)</li>`)
})
console.log(' </ul></li>')
console.log('</ul></p></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>Value</th><th>Description</th>')
console.log('</thead><tbody>')
type.enumValues.forEach(value => {
console.log(' <tr>')
console.log(` <td valign="top">**${value.name}**</td>`)
console.log(` <td>${markdown(value.description)}</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 => {
console.log(`### ${type.name}\n`)
if (type.description) {
console.log(`${type.description}\n`)
}
})

View file

@ -208,13 +208,22 @@ export const places = linkedQuery(PlaceConnection)
export const recordings = linkedQuery(RecordingConnection)
export const releases = linkedQuery(ReleaseConnection, {
args: {
type: { type: new GraphQLList(ReleaseGroupType) },
status: { type: new GraphQLList(ReleaseStatus) }
type: {
type: new GraphQLList(ReleaseGroupType),
description: 'Filter by one or more release group types.'
},
status: {
type: new GraphQLList(ReleaseStatus),
description: 'Filter by one or more release statuses.'
}
}
})
export const releaseGroups = linkedQuery(ReleaseGroupConnection, {
args: {
type: { type: new GraphQLList(ReleaseGroupType) }
type: {
type: new GraphQLList(ReleaseGroupType),
description: 'Filter by one or more release group types.'
}
}
})
export const tags = linkedQuery(TagConnection, {

View file

@ -6,8 +6,17 @@ export default new GraphQLObjectType({
description: `Fields indicating the begin and end date of an entitys
lifetime, including whether it has ended (even if the date is unknown).`,
fields: () => ({
begin: { type: DateType },
end: { type: DateType },
ended: { type: GraphQLBoolean }
begin: {
type: DateType,
description: 'The start date of the entitys life span.'
},
end: {
type: DateType,
description: 'The end date of the entitys life span.'
},
ended: {
type: GraphQLBoolean,
description: 'Whether or not the entitys life span has ended.'
}
})
})