diff --git a/src/index.js b/src/index.js index e46172f3..88267bc0 100755 --- a/src/index.js +++ b/src/index.js @@ -5,6 +5,7 @@ const resolveFrom = require('resolve-from') const { loadSchemaJSON, schemaToJSON } = require('./loadSchemaJSON') const renderSchema = require('./renderSchema') const updateSchema = require('./updateSchema') +const updateSchemaByKind = require('./updateSchemaByKind') const diffSchema = require('./diffSchema') function safeExit(code) { @@ -39,6 +40,14 @@ function printHelp(console) { create (if the file does not exist) --require If importing the schema from a module, require the specified module first (useful for e.g. babel-register) + --by-kind Split markdown by kind (default: false) + - Query + - Mutation + - Objects + - Inputs + - Enums + - Scalar + - Interfaces --version Print version and exit `) } @@ -47,7 +56,10 @@ function run( argv = process.argv.slice(2), { console = global.console, exit = true } = {} ) { - const args = parseArgs(argv) + const args = parseArgs(argv, { + boolean: 'by-kind', + default: { 'by-kind': false } + }) if (args.help) { printHelp(console) @@ -97,6 +109,29 @@ function run( safeExit(1) } }) + } else if (args['by-kind']) { + ;[ + 'Query.md', + 'Mutation.md', + 'Objects.md', + 'InputObjects.md', + 'Enums.md', + 'Scalars.md', + 'Interfaces.md' + ].forEach(item => { + updateSchemaByKind(item, schema, options) + .then(() => { + if (exit) { + safeExit(0) + } + }) + .catch(err => { + console.error(err) + if (exit) { + safeExit(1) + } + }) + }) } else { renderSchema(schema, options) if (exit) { diff --git a/src/renderSchema.js b/src/renderSchema.js index cf7d68d8..8da17890 100644 --- a/src/renderSchema.js +++ b/src/renderSchema.js @@ -10,13 +10,15 @@ function sortBy(arr, property) { } function renderType(type, options) { + const appendObjectUrl = options.appendObjectUrl || '' + if (type.kind === 'NON_NULL') { return renderType(type.ofType, options) + '!' } if (type.kind === 'LIST') { return `[${renderType(type.ofType, options)}]` } - const url = options.getTypeURL(type) + const url = options.getTypeURL(type, appendObjectUrl) return url ? `${type.name}` : type.name } @@ -27,9 +29,12 @@ function renderObject(type, options) { const headingLevel = options.headingLevel || 1 const getTypeURL = options.getTypeURL const isInputObject = type.kind === 'INPUT_OBJECT' + const hasPrefix = options.hasPrefix || false if (!skipTitle) { - printer(`\n${'#'.repeat(headingLevel + 2)} ${type.name}\n`) + printer( + `\n${'#'.repeat(headingLevel + (hasPrefix ? 1 : 2))} ${type.name}\n` + ) } if (type.description) { printer(`${type.description}\n`) @@ -57,7 +62,12 @@ function renderObject(type, options) { field.isDeprecated ? ' ⚠️' : '' }` ) - printer(`${renderType(field.type, { getTypeURL })}`) + printer( + `${renderType(field.type, { + getTypeURL, + appendObjectUrl: hasPrefix + })}` + ) if (field.description || field.isDeprecated) { printer('') if (field.description) { @@ -80,7 +90,12 @@ function renderObject(type, options) { field.args.forEach((arg, i) => { printer('') printer(`${arg.name}`) - printer(`${renderType(arg.type, { getTypeURL })}`) + printer( + `${renderType(arg.type, { + getTypeURL, + appendObjectUrl: hasPrefix + })}` + ) if (arg.description) { printer('') printer(`\n${arg.description}\n`) @@ -105,6 +120,7 @@ function renderSchema(schema, options) { const printer = options.printer || console.log const headingLevel = options.headingLevel || 1 const unknownTypeURL = options.unknownTypeURL + const itemType = options.itemType || false if (schema.__schema) { schema = schema.__schema @@ -114,8 +130,18 @@ function renderSchema(schema, options) { const typeMap = schema.types.reduce((typeMap, type) => { return Object.assign(typeMap, { [type.name]: type }) }, {}) - const getTypeURL = type => { - const url = `#${type.name.toLowerCase()}` + const getTypeURL = (type, hasPrefix = false) => { + const prefix = hasPrefix + ? type.kind + .split('_') + .map(i => { + return i.charAt(0).toUpperCase() + i.slice(1).toLowerCase() + }) + .join('') + 's.html' + : '' + + const url = `${prefix}#${type.name.toLowerCase()}` + if (typeMap[type.name]) { return url } else if (typeof unknownTypeURL === 'function') { @@ -145,95 +171,134 @@ function renderSchema(schema, options) { sortBy(scalars, 'name') sortBy(interfaces, 'name') - if (!skipTitle) { - printer(`${'#'.repeat(headingLevel)} ${title}\n`) - } + if (!itemType) { + if (!skipTitle) { + printer(`${'#'.repeat(headingLevel)} ${title}\n`) + } - if (prologue) { - printer(`${prologue}\n`) - } + if (prologue) { + printer(`${prologue}\n`) + } - printer('
') - printer(' Table of Contents\n') - if (query) { - printer(' * [Query](#query)') - } - if (mutation) { - printer(' * [Mutation](#mutation)') - } - if (objects.length) { - printer(' * [Objects](#objects)') - objects.forEach(type => { - printer(` * [${type.name}](#${type.name.toLowerCase()})`) - }) - } - if (inputs.length) { - printer(' * [Inputs](#inputs)') - inputs.forEach(type => { - printer(` * [${type.name}](#${type.name.toLowerCase()})`) - }) - } - if (enums.length) { - printer(' * [Enums](#enums)') - enums.forEach(type => { - printer(` * [${type.name}](#${type.name.toLowerCase()})`) - }) - } - if (scalars.length) { - printer(' * [Scalars](#scalars)') - scalars.forEach(type => { - printer(` * [${type.name}](#${type.name.toLowerCase()})`) - }) - } - if (interfaces.length) { - printer(' * [Interfaces](#interfaces)') - interfaces.forEach(type => { - printer(` * [${type.name}](#${type.name.toLowerCase()})`) - }) + printer('
') + printer(' Table of Contents\n') + if (query) { + printer(' * [Query](#query)') + } + if (mutation) { + printer(' * [Mutation](#mutation)') + } + if (objects.length) { + printer(' * [Objects](#objects)') + objects.forEach(type => { + printer(` * [${type.name}](#${type.name.toLowerCase()})`) + }) + } + if (inputs.length) { + printer(' * [Inputs](#inputs)') + inputs.forEach(type => { + printer(` * [${type.name}](#${type.name.toLowerCase()})`) + }) + } + if (enums.length) { + printer(' * [Enums](#enums)') + enums.forEach(type => { + printer(` * [${type.name}](#${type.name.toLowerCase()})`) + }) + } + if (scalars.length) { + printer(' * [Scalars](#scalars)') + scalars.forEach(type => { + printer(` * [${type.name}](#${type.name.toLowerCase()})`) + }) + } + if (interfaces.length) { + printer(' * [Interfaces](#interfaces)') + interfaces.forEach(type => { + printer(` * [${type.name}](#${type.name.toLowerCase()})`) + }) + } + printer('\n
') } - printer('\n
') - if (query) { + if ((query && !itemType) || (itemType === 'Query' && query)) { printer( `\n${'#'.repeat(headingLevel + 1)} Query${ query.name === 'Query' ? '' : ' (' + query.name + ')' }` ) - renderObject(query, { skipTitle: true, headingLevel, printer, getTypeURL }) + renderObject(query, { + skipTitle: true, + headingLevel, + printer, + getTypeURL, + hasPrefix: !!itemType + }) } - if (mutation) { - printer( - `\n${'#'.repeat(headingLevel + 1)} Mutation${ - mutation.name === 'Mutation' ? '' : ' (' + mutation.name + ')' - }` - ) + if ((mutation && !itemType) || (itemType === 'Mutation' && mutation)) { + if (!itemType) { + printer( + `\n${'#'.repeat(headingLevel + 1)} Mutation${ + mutation.name === 'Mutation' ? '' : ' (' + mutation.name + ')' + }` + ) + } + renderObject(mutation, { skipTitle: true, headingLevel, printer, - getTypeURL + getTypeURL, + hasPrefix: !!itemType }) } - if (objects.length) { - printer(`\n${'#'.repeat(headingLevel + 1)} Objects`) + if ( + (objects.length && !itemType) || + (itemType === 'Objects' && objects.length) + ) { + if (!itemType) { + printer(`\n${'#'.repeat(headingLevel + 1)} Objects`) + } + objects.forEach(type => - renderObject(type, { headingLevel, printer, getTypeURL }) + renderObject(type, { + headingLevel, + printer, + getTypeURL, + hasPrefix: !!itemType + }) ) } - if (inputs.length) { - printer(`\n${'#'.repeat(headingLevel + 1)} Inputs`) + if ( + (inputs.length && !itemType) || + (itemType === 'InputObjects' && inputs.length) + ) { + if (!itemType) { + printer(`\n${'#'.repeat(headingLevel + 1)} Inputs`) + } + inputs.forEach(type => - renderObject(type, { headingLevel, printer, getTypeURL }) + renderObject(type, { + headingLevel, + printer, + getTypeURL, + hasPrefix: !!itemType + }) ) } - if (enums.length) { - printer(`\n${'#'.repeat(headingLevel + 1)} Enums`) + if ((enums.length && !itemType) || (itemType === 'Enums' && enums.length)) { + if (!itemType) { + printer(`\n${'#'.repeat(headingLevel + 1)} Enums`) + } + enums.forEach(type => { - printer(`\n${'#'.repeat(headingLevel + 2)} ${type.name}\n`) + printer( + `\n${'#'.repeat(headingLevel + (!itemType ? 2 : 1))} ${type.name}\n` + ) if (type.description) { printer(`${type.description}\n`) } @@ -274,20 +339,39 @@ function renderSchema(schema, options) { }) } - if (scalars.length) { - printer(`\n${'#'.repeat(headingLevel + 1)} Scalars\n`) + if ( + (scalars.length && !itemType) || + (itemType === 'Scalars' && scalars.length) + ) { + if (!itemType) { + printer(`\n${'#'.repeat(headingLevel + 1)} Scalars\n`) + } + scalars.forEach(type => { - printer(`${'#'.repeat(headingLevel + 2)} ${type.name}\n`) + printer( + `${'#'.repeat(headingLevel + (!itemType ? 2 : 1))} ${type.name}\n` + ) if (type.description) { printer(`${type.description}\n`) } }) } - if (interfaces.length) { - printer(`\n${'#'.repeat(headingLevel + 1)} Interfaces\n`) + if ( + (interfaces.length && !itemType) || + (itemType === 'Interfaces' && interfaces.length) + ) { + if (!itemType) { + printer(`\n${'#'.repeat(headingLevel + 1)} Interfaces\n`) + } + interfaces.forEach(type => - renderObject(type, { headingLevel, printer, getTypeURL }) + renderObject(type, { + headingLevel, + printer, + getTypeURL, + hasPrefix: !!itemType + }) ) } diff --git a/src/updateSchemaByKind.js b/src/updateSchemaByKind.js new file mode 100644 index 00000000..a8beee19 --- /dev/null +++ b/src/updateSchemaByKind.js @@ -0,0 +1,16 @@ +const fs = require('fs') +const updateSchema = require('./updateSchema') + +function updateSchemaByKind(item, schema, options) { + try { + // Create file if not exists + fs.closeSync(fs.openSync(item, 'a')) + const itemType = item.replace('.md', '') + + return updateSchema(`./${item}`, schema, { itemType, ...options }) + } catch (err) { + console.error(err) + } +} + +module.exports = updateSchemaByKind diff --git a/test/__snapshots__/index.test.js.snap b/test/__snapshots__/index.test.js.snap index e5022502..dfa93c89 100644 --- a/test/__snapshots__/index.test.js.snap +++ b/test/__snapshots__/index.test.js.snap @@ -477,6 +477,14 @@ Object { create (if the file does not exist) --require If importing the schema from a module, require the specified module first (useful for e.g. babel-register) + --by-kind Split markdown by kind (default: false) + - Query + - Mutation + - Objects + - Inputs + - Enums + - Scalar + - Interfaces --version Print version and exit ", @@ -510,6 +518,14 @@ Object { create (if the file does not exist) --require If importing the schema from a module, require the specified module first (useful for e.g. babel-register) + --by-kind Split markdown by kind (default: false) + - Query + - Mutation + - Objects + - Inputs + - Enums + - Scalar + - Interfaces --version Print version and exit ",