1 | #!/usr/bin/env node
|
2 | 'use strict'
|
3 | const parseArgs = require('minimist')
|
4 | const resolveFrom = require('resolve-from')
|
5 | const { loadSchemaJSON, schemaToJSON } = require('./loadSchemaJSON')
|
6 | const renderSchema = require('./renderSchema')
|
7 | const updateSchema = require('./updateSchema')
|
8 | const diffSchema = require('./diffSchema')
|
9 |
|
10 | function safeExit(code) {
|
11 | process.on('exit', function () {
|
12 | process.exit(code)
|
13 | })
|
14 | }
|
15 |
|
16 | function 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 |
|
49 | function 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 |
|
125 | module.exports = {
|
126 | run,
|
127 | loadSchemaJSON,
|
128 | schemaToJSON,
|
129 | renderSchema,
|
130 | updateSchema,
|
131 | diffSchema,
|
132 | }
|
133 |
|
134 | if (require.main === module) {
|
135 | run()
|
136 | }
|