-
Notifications
You must be signed in to change notification settings - Fork 1.7k
/
cli.ts
142 lines (134 loc) · 4.08 KB
/
cli.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
/**
* Copyright (c) 2021 GraphQL Contributors
* All rights reserved.
*
* This source code is licensed under the license found in the
* LICENSE file in the root directory of this source tree.
*
*/
import yargs from 'yargs';
import client from './client';
import { startServer } from 'graphql-language-service-server';
const { argv } = yargs
.usage(
'GraphQL Language Service Command-Line Interface.\n' +
'Usage: graphql-lsp <command> <file>\n' +
' [-h | --help]\n' +
' [-c | --configDir] {configDir}\n' +
' [-t | --text] {textBuffer}\n' +
' [-f | --file] {filePath}\n' +
' [-s | --schema] {schemaPath}\n' +
' [-m | --method] {method}\n' +
' [-p | --port] {port}\n' +
'\n At least one command is required.\n',
)
.help('h')
.alias('h', 'help')
.strict()
.recommendCommands()
.demandCommand(
1,
'At least one command is required.\n' +
'Commands: "server, validate, autocomplete, outline"\n',
)
.command('server', 'GraphQL language server service')
.command('validate', 'Validates the query')
.command('autocomplete', 'Get autocomplete suggestions')
.command('outline', 'Get outline')
.option('t', {
alias: 'text',
describe:
'Text buffer to perform GraphQL diagnostics on.\n' +
'Will defer to --file option if omitted.\n' +
'Overrides the --file option, if any.\n',
type: 'string',
})
.option('f', {
alias: 'file',
describe:
'File path to perform GraphQL diagnostics on.\n' +
'Will be ignored if --text option is supplied.\n',
type: 'string',
})
.option('row', {
describe:
'A row number from the cursor location for ' +
'GraphQL autocomplete suggestions.\n' +
'If omitted, the last row number will be used.\n',
type: 'number',
})
.option('column', {
describe:
'A column number from the cursor location for ' +
'GraphQL autocomplete suggestions.\n' +
'If omitted, the last column number will be used.\n',
type: 'number',
})
.option('c', {
alias: 'configDir',
describe:
'Path to the .graphqlrc configuration file.\n' +
'Walks up the directory tree from the provided config directory, or ' +
'the current working directory, until a .graphqlrc is found or ' +
'the root directory is found.\n',
type: 'string',
})
.option('m', {
alias: 'method',
describe:
'A IPC communication method between client and server.\n' +
'Can be one of: stream, node, socket.\n' +
'Will default to use a node IPC channel for communication.\n',
type: 'string',
default: 'node',
})
.option('p', {
alias: 'port',
describe:
'Port number to communicate via socket.\n' +
'The port number of a service running inside the IDE that the language ' +
'service should connect to.\n' +
'Required if the client communicates via socket connection.\n',
type: 'number',
})
.option('s', {
alias: 'schemaPath',
describe: 'a path to schema DSL file\n',
type: 'string',
});
const command = argv._.pop();
if (!command) {
process.stdout.write('no command supplied');
process.exit(0);
}
if (command === 'server') {
process.on('uncaughtException', error => {
process.stderr.write(
'An error was thrown from GraphQL language service: ' + String(error),
);
// don't exit at all if there is an uncaughtException
// process.exit(0);
});
const options: { [key: string]: any } = {};
if (argv.port) {
options.port = argv.port;
}
if (argv.method) {
options.method = argv.method;
}
if (argv.configDir) {
options.configDir = argv.configDir;
}
// eslint-disable-next-line promise/prefer-await-to-then -- don't know if I can use top level await here
startServer(options).catch(error => {
process.stderr.write(
'An error was thrown from GraphQL language service: ' + String(error),
);
});
} else {
client(command as string, argv as Record<string, string>);
}
// Exit the process when stream closes from remote end.
process.stdin.on('close', () => {
process.exit(0);
});