UNPKG

5.79 kBJavaScriptView Raw
1#!/usr/bin/env node
2
3// this tool requires async/await, and therefore Node.js 8.3+
4
5'use strict';
6
7const fs = require('fs');
8
9const yaml = require('yaml');
10const fetch = require('node-fetch-h2');
11const bae = require('better-ajv-errors');
12
13const swagger2openapi = require('./index.js');
14const validator = require('oas-validator');
15
16process.exitCode = 1;
17
18let argv = require('yargs')
19 .boolean('anchors')
20 .describe('anchors','allow use of YAML anchors/aliases')
21 .boolean('all')
22 .alias('a','all')
23 .describe('all','show all lint warnings')
24 .boolean('bae')
25 .alias('b','bae')
26 .describe('bae','enable better-ajv-errors')
27 .string('encoding')
28 .alias('e','encoding')
29 .default('encoding','utf8')
30 .describe('encoding','text encoding to use')
31 .boolean('force')
32 .alias('f','force')
33 .describe('force','output even if validation/lint failures')
34 .boolean('internal')
35 .alias('i','internal')
36 .describe('internal','resolve internal $refs also')
37 .boolean('json')
38 .alias('j','json')
39 .describe('json','output validation/lint errors in JSON format')
40 .boolean('lint')
41 .describe('lint','also lint the document')
42 .alias('l','lint')
43 .array('lintSkip')
44 .describe('lintSkip','linter rule name(s) to skip')
45 .alias('s','lintSkip')
46 .boolean('dumpMeta')
47 .alias('m','dumpMeta')
48 .describe('dumpMeta','Dump definition metadata')
49 .string('output')
50 .alias('o','output')
51 .describe('output','outfile file to write to, default STDOUT')
52 .boolean('prevalidate')
53 .alias('p','prevalidate')
54 .describe('prevalidate','validate $ref\'d files separately')
55 .count('quiet')
56 .alias('q','quiet')
57 .describe('quiet','reduce verbosity')
58 .count('verbose')
59 .default('verbose',1)
60 .alias('v','verbose')
61 .describe('verbose','increase verbosity')
62 .demand(1)
63 .argv;
64
65function main(){
66 return new Promise(async function(resolve,reject){
67 const ruleUrls = new Set();
68 argv.resolve = true;
69 argv.patch = true;
70 argv.source = argv._[0];
71 if (argv.all) argv.lintLimit = Number.MAX_SAFE_INTEGER;
72 if (argv.bae) {
73 argv.validateSchema = 'first';
74 argv.prettify = true;
75 }
76 if (argv.internal) {
77 argv.resolveInternal = true;
78 }
79 argv.verbose = argv.verbose - argv.quiet;
80 let options = {};
81 let result = false;
82 let jsonOutput = {};
83 try {
84 if (argv.source.startsWith('http')) {
85 options = await swagger2openapi.convertUrl(argv.source,argv);
86 }
87 else {
88 options = await swagger2openapi.convertFile(argv.source,argv);
89 }
90 result = await validator.validateInner(options.openapi,options);
91 }
92 catch (ex) {
93 let path;
94 if (options.context) {
95 path = options.context.pop();
96 }
97 if (options.json) {
98 jsonOutput.error = ex.message;
99 if (options.verbose > 1) jsonOutput.stacktrace = ex.stack;
100 if (path) {
101 jsonOutput.path = path;
102 }
103 }
104 else {
105 console.warn(ex.message);
106 if (options.verbose > 1) console.warn(ex.stack);
107 if (path) {
108 console.warn(path);
109 }
110 }
111 jsonOutput.warnings = [];
112 if (options.warnings) {
113 for (let warning of options.warnings) {
114 if (argv.bae) {
115 const display = bae(options.schema,options.openapi,[warning]);
116 console.warn(display);
117 }
118 else if (options.json) {
119 jsonOutput.warnings.push({ message:warning.message, pointer:warning.pointer, ruleName:warning.ruleName, ruleUrl:warning.rule.url });
120 }
121 else {
122 console.warn(warning.message,warning.pointer,warning.ruleName);
123 if (warning.rule.url) ruleUrls.add(warning.rule.url+'#'+warning.ruleName);
124 }
125 }
126 }
127 reject(ex);
128 }
129 if ((ruleUrls.size > 0) && (!options.json)) {
130 console.warn('For more information, visit:');
131 for (let url of ruleUrls) {
132 console.warn(url);
133 }
134 }
135 if (argv.dumpMeta) {
136 if (options.json) {
137 jsonOutput.metadata = options.metadata;
138 }
139 else {
140 console.warn('\n#Definition metadata:');
141 console.warn(yaml.stringify(options.metadata,{depth:Math.INFINITY}));
142 }
143 }
144 if (options.json) {
145 console.warn(JSON.stringify(jsonOutput, null, 2));
146 }
147 if (result || argv.force) {
148 if (options.output) {
149 if (options.sourceYaml) {
150 fs.writeFileSync(options.output, yaml.stringify(options.openapi),options.encoding);
151 }
152 else {
153 fs.writeFileSync(options.output, JSON.stringify(options.openapi,null,2),options.encoding);
154 }
155 }
156 else if (argv.verbose >= 1) {
157 if (options.sourceYaml) {
158 console.log(yaml.stringify(options.openapi));
159 }
160 else {
161 console.log(JSON.stringify(options.openapi,null,2));
162 }
163 }
164 }
165 resolve(options.openapi);
166 });
167}
168
169main()
170.then(function(options){
171 process.exitCode = 0;
172})
173.catch(function(err){
174 //if (!argv.json) console.warn(err.message);
175});
176