forked from Open-MBEE/openapi-graph-extractor
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathcli.ts
146 lines (126 loc) · 4.01 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
143
144
145
146
import type {
OpenAPIV2, OpenAPIV3,
O,
Arguments,
} from './deps.ts';
import {
path,
yargs,
YargsInstance,
parseYaml,
} from './deps.ts';
import {extract} from './src/extract.ts';
import {CompatibleDocument, ServiceConfigOpenApiV2} from './src/exporter.ts';
yargs(Deno.args)
.command('extract <config-script> [api-document]', 'run the extraction using the given congiruation script and optionally OpenAPI document',
(y_yargs_extract: YargsInstance) => y_yargs_extract
.positional('config-script', {
describe: 'the configuration script as JavaScript or TypeScript',
})
.positional('api-document', {
describe: 'the OpenAPI document can be a local file or remote URL, and be either in JSON or YAML format',
}),
async(g_argv: Arguments) => {
// import the configuration script
let gc_service: ServiceConfigOpenApiV2<OpenAPIV2.Document>;
try {
const p_script = path.resolve(Deno.cwd(), g_argv.configScript);
({default:gc_service} = await import(p_script));
}
catch(e_import) {
throw new Error(`Failed to import the configuration script: ${e_import.message}`);
}
// path to document
let p_document = g_argv.apiDocument;
// document definition
let g_document!: CompatibleDocument<OpenAPIV2.Document>;
// config provides string for document
if('string' === typeof gc_service.openApiDocument) {
p_document = gc_service.openApiDocument;
}
// config provides full document
else if('object' === typeof gc_service.openApiDocument) {
g_document = gc_service.openApiDocument;
}
// no document specified in config nor cli
else if('string' !== typeof g_argv.apiDocument) {
throw new Error(`No document was specified in config, must provide one in CLI arg`);
}
// document struct was not defined, resolve path
if(!g_document) {
let s_document = '';
// remote URL
if(/^[a-z]+:\/\//.test(p_document)) {
// attempt to fetch the remote document
let d_res: Response;
try {
d_res = await fetch(p_document, {
headers: {
accept: 'application/json,application/yaml',
},
redirect: 'follow',
});
}
catch(e_fetch) {
throw new Error(`Failed to fetch remote API document from <${p_document}>: ${e_fetch.message}`);
}
// prep response text
let s_response = '';
// parse response data as text
try {
s_response = await d_res.text();
}
catch(e_text) {
throw new Error(`Remote server returned unparseable binary data for <${p_document}>`);
}
// not an ok HTTP response status code
if(!d_res.ok) {
throw new Error(`Remote server returned non-200 response to document fetch request <${p_document}>: ${d_res.status} \n${s_response}`);
}
// set document source
s_document = s_response;
}
// local file
else {
// attempt to read as UTF-8
try {
s_document = await Deno.readTextFileSync(p_document);
}
catch(e_read) {
throw new Error(`Failed to read local API document file ${p_document} : ${e_read.message}`);
}
}
// document is JSON
if(/^\s*\{/.test(s_document)) {
// attempt to parse
try {
g_document = JSON.parse(s_document);
}
catch(e_parse) {
throw new Error(`Failed to parse document as JSON: ${e_parse.message}`);
}
}
// document is YAML
else {
try {
g_document = parseYaml(s_document);
}
catch(e_parse) {
throw new Error(`Failed to parse document as YAML: ${e_parse.message}`);
}
}
}
// validate shape
if('object' !== typeof g_document.paths) {
throw new Error(`The parsed document does not have the expected shape. Are you sure the file is properly formatted?`);
}
// re-assign the document struct
gc_service.openApiDocument = g_document;
// fire document loaded hook
const g_augmentation = await gc_service.documentLoaded?.(g_document);
// run the extraction
await extract(gc_service, g_augmentation);
})
.strictCommands()
.demandCommand(1)
.parse();