UNPKG

4.22 kBJavaScriptView Raw
1#!/usr/bin/env node
2'use strict'
3const parseArgs = require('minimist')
4const resolveFrom = require('resolve-from')
5const { loadSchemaJSON, schemaToJSON } = require('./loadSchemaJSON')
6const renderSchema = require('./renderSchema')
7const updateSchema = require('./updateSchema')
8const diffSchema = require('./diffSchema')
9
10function safeExit(code) {
11 process.on('exit', function () {
12 process.exit(code)
13 })
14}
15
16function printHelp(console) {
17 const name = require('../package.json').name
18 console.log(`
19 Usage: ${name} [options] <schema>
20
21 Output a Markdown document with rendered descriptions and links between types.
22 The schema may be specified as:
23
24 - a URL to the GraphQL endpoint (the introspection query will be run)
25 - a GraphQL document containing the schema (.graphql or .gql)
26 - a JSON document containing the schema (as returned by the introspection query)
27 - an importable module with the schema as its default export (either an instance
28 of GraphQLSchema or a JSON object)
29
30 Options:
31
32 --title <string> Change the top heading title (default: 'Schema Types')
33 --no-title Do not print a default title
34 --no-toc Do not print table of contents
35 --prologue <string> Include custom Markdown after the title
36 --epilogue <string> Include custom Markdown after everything else
37 --heading-level <num> Heading level to begin at, useful if you are embedding the
38 output in a document with other sections (default: 1)
39 --update-file <file> Markdown document to update (between comment markers) or
40 create (if the file does not exist)
41 --require <module> If importing the schema from a module, require the specified
42 module first (useful for e.g. babel-register)
43 --header <name=value> Additional header(s) to use in GraphQL request
44 e.g. --header "Authorization=Bearer ey..."
45 --version Print version and exit
46`)
47}
48
49function run(
50 argv = process.argv.slice(2),
51 { console = global.console, exit = true } = {}
52) {
53 const args = parseArgs(argv)
54
55 if (args.help) {
56 printHelp(console)
57 } else if (args.version) {
58 console.log(require('../package.json').version)
59 } else if (args._.length === 1) {
60 if (args.require) {
61 const requirePath = resolveFrom('.', args.require)
62 if (requirePath) {
63 require(requirePath)
64 } else {
65 throw new Error(`Could not resolve --require module: ${args.require}`)
66 }
67 }
68 const schemaPath = args._[0]
69 const headers = [].concat(args.header || []).reduce((obj, header) => {
70 const [key, ...value] = String(header).split('=')
71 obj[key] = value.join('=')
72 return obj
73 }, {})
74 const loadOptions = { headers }
75 loadSchemaJSON(schemaPath, loadOptions).then((schema) => {
76 const options = {
77 title: args.title,
78 skipTitle: false,
79 prologue: args.prologue,
80 epilogue: args.epilogue,
81 skipTableOfContents: args.toc === false,
82 headingLevel: args['heading-level'],
83 }
84 if (options.title === false) {
85 options.title = ''
86 options.skipTitle = true
87 } else if (Array.isArray(options.title)) {
88 options.title.forEach((value) => {
89 if (typeof value === 'string') {
90 options.title = value
91 } else if (value === false) {
92 options.skipTitle = true
93 }
94 })
95 }
96 const updateFile = args['update-file']
97 if (updateFile) {
98 updateSchema(updateFile, schema, options)
99 .then(() => {
100 if (exit) {
101 safeExit(0)
102 }
103 })
104 .catch((err) => {
105 console.error(err)
106 if (exit) {
107 safeExit(1)
108 }
109 })
110 } else {
111 renderSchema(schema, options)
112 if (exit) {
113 safeExit(0)
114 }
115 }
116 })
117 } else {
118 printHelp(console)
119 if (exit) {
120 safeExit(1)
121 }
122 }
123}
124
125module.exports = {
126 run,
127 loadSchemaJSON,
128 schemaToJSON,
129 renderSchema,
130 updateSchema,
131 diffSchema,
132}
133
134if (require.main === module) {
135 run()
136}