@@ -11,191 +11,180 @@ const { ono } = require("@jsdevtools/ono");
11
11
const $RefParser = require ( "@apidevtools/json-schema-ref-parser" ) ;
12
12
const dereference = require ( "@apidevtools/json-schema-ref-parser/lib/dereference" ) ;
13
13
14
- module . exports = SwaggerParser ;
15
-
16
14
/**
17
15
* This class parses a Swagger 2.0 or 3.0 API, resolves its JSON references and their resolved values,
18
16
* and provides methods for traversing, dereferencing, and validating the API.
19
17
*
20
18
* @class
21
19
* @augments $RefParser
22
20
*/
23
- function SwaggerParser ( ) {
24
- $RefParser . apply ( this , arguments ) ;
25
- }
26
-
27
- util . inherits ( SwaggerParser , $RefParser ) ;
28
- SwaggerParser . parse = $RefParser . parse ;
29
- SwaggerParser . resolve = $RefParser . resolve ;
30
- SwaggerParser . bundle = $RefParser . bundle ;
31
- SwaggerParser . dereference = $RefParser . dereference ;
32
-
33
- /**
34
- * Alias {@link $RefParser#schema} as {@link SwaggerParser#api}
35
- */
36
- Object . defineProperty ( SwaggerParser . prototype , "api" , {
37
- configurable : true ,
38
- enumerable : true ,
39
- get ( ) {
40
- return this . schema ;
41
- }
42
- } ) ;
43
-
44
- /**
45
- * Parses the given Swagger API.
46
- * This method does not resolve any JSON references.
47
- * It just reads a single file in JSON or YAML format, and parse it as a JavaScript object.
48
- *
49
- * @param {string } [path] - The file path or URL of the JSON schema
50
- * @param {object } [api] - The Swagger API object. This object will be used instead of reading from `path`.
51
- * @param {ParserOptions } [options] - Options that determine how the API is parsed
52
- * @param {Function } [callback] - An error-first callback. The second parameter is the parsed API object.
53
- * @returns {Promise } - The returned promise resolves with the parsed API object.
54
- */
55
- SwaggerParser . prototype . parse = async function ( path , api , options , callback ) {
56
- let args = normalizeArgs ( arguments ) ;
57
- args . options = new Options ( args . options ) ;
58
-
59
- try {
60
- let schema = await $RefParser . prototype . parse . call ( this , args . path , args . schema , args . options ) ;
61
-
62
- if ( schema . swagger ) {
63
- // Verify that the parsed object is a Swagger API
64
- if ( schema . swagger === undefined || schema . info === undefined || schema . paths === undefined ) {
65
- throw ono . syntax ( `${ args . path || args . schema } is not a valid Swagger API definition` ) ;
66
- }
67
- else if ( typeof schema . swagger === "number" ) {
68
- // This is a very common mistake, so give a helpful error message
69
- throw ono . syntax ( 'Swagger version number must be a string (e.g. "2.0") not a number.' ) ;
70
- }
71
- else if ( typeof schema . info . version === "number" ) {
72
- // This is a very common mistake, so give a helpful error message
73
- throw ono . syntax ( 'API version number must be a string (e.g. "1.0.0") not a number.' ) ;
74
- }
75
- else if ( schema . swagger !== "2.0" ) {
76
- throw ono . syntax ( `Unrecognized Swagger version: ${ schema . swagger } . Expected 2.0` ) ;
21
+ class SwaggerParser extends $RefParser {
22
+
23
+ /**
24
+ * Parses the given Swagger API.
25
+ * This method does not resolve any JSON references.
26
+ * It just reads a single file in JSON or YAML format, and parse it as a JavaScript object.
27
+ *
28
+ * @param {string } [path] - The file path or URL of the JSON schema
29
+ * @param {object } [api] - The Swagger API object. This object will be used instead of reading from `path`.
30
+ * @param {ParserOptions } [options] - Options that determine how the API is parsed
31
+ * @param {Function } [callback] - An error-first callback. The second parameter is the parsed API object.
32
+ * @returns {Promise } - The returned promise resolves with the parsed API object.
33
+ */
34
+ async parse ( path , api , options , callback ) {
35
+ let args = normalizeArgs ( arguments ) ;
36
+ args . options = new Options ( args . options ) ;
37
+
38
+ try {
39
+ let schema = await super . parse ( args . path , args . schema , args . options ) ;
40
+
41
+ if ( schema . swagger ) {
42
+ // Verify that the parsed object is a Swagger API
43
+ if ( schema . swagger === undefined || schema . info === undefined || schema . paths === undefined ) {
44
+ throw ono . syntax ( `${ args . path || args . schema } is not a valid Swagger API definition` ) ;
45
+ }
46
+ else if ( typeof schema . swagger === "number" ) {
47
+ // This is a very common mistake, so give a helpful error message
48
+ throw ono . syntax ( 'Swagger version number must be a string (e.g. "2.0") not a number.' ) ;
49
+ }
50
+ else if ( typeof schema . info . version === "number" ) {
51
+ // This is a very common mistake, so give a helpful error message
52
+ throw ono . syntax ( 'API version number must be a string (e.g. "1.0.0") not a number.' ) ;
53
+ }
54
+ else if ( schema . swagger !== "2.0" ) {
55
+ throw ono . syntax ( `Unrecognized Swagger version: ${ schema . swagger } . Expected 2.0` ) ;
56
+ }
77
57
}
78
- }
79
- else {
80
- let supportedVersions = [ "3.0.0" , "3.0.1" , "3.0.2" , "3.0.3" , "3.1.0" ] ;
58
+ else {
59
+ let supportedVersions = [ "3.0.0" , "3.0.1" , "3.0.2" , "3.0.3" , "3.1.0" ] ;
81
60
82
- // Verify that the parsed object is a Openapi API
83
- if ( schema . openapi === undefined || schema . info === undefined ) {
84
- throw ono . syntax ( `${ args . path || args . schema } is not a valid Openapi API definition` ) ;
85
- }
86
- else if ( schema . paths === undefined ) {
87
- if ( schema . openapi === "3.1.0" ) {
88
- if ( schema . webhooks === undefined ) {
61
+ // Verify that the parsed object is a Openapi API
62
+ if ( schema . openapi === undefined || schema . info === undefined ) {
63
+ throw ono . syntax ( `${ args . path || args . schema } is not a valid Openapi API definition` ) ;
64
+ }
65
+ else if ( schema . paths === undefined ) {
66
+ if ( schema . openapi === "3.1.0" ) {
67
+ if ( schema . webhooks === undefined ) {
68
+ throw ono . syntax ( `${ args . path || args . schema } is not a valid Openapi API definition` ) ;
69
+ }
70
+ }
71
+ else {
89
72
throw ono . syntax ( `${ args . path || args . schema } is not a valid Openapi API definition` ) ;
90
73
}
91
74
}
92
- else {
93
- throw ono . syntax ( `${ args . path || args . schema } is not a valid Openapi API definition` ) ;
75
+ else if ( typeof schema . openapi === "number" ) {
76
+ // This is a very common mistake, so give a helpful error message
77
+ throw ono . syntax ( 'Openapi version number must be a string (e.g. "3.0.0") not a number.' ) ;
94
78
}
95
- }
96
- else if ( typeof schema . openapi === "number" ) {
97
- // This is a very common mistake, so give a helpful error message
98
- throw ono . syntax ( 'Openapi version number must be a string (e.g. "3.0.0") not a number.' ) ;
99
- }
100
- else if ( typeof schema . info . version === "number" ) {
101
- // This is a very common mistake, so give a helpful error message
102
- throw ono . syntax ( 'API version number must be a string (e.g. "1.0.0") not a number.' ) ;
103
- }
104
- else if ( supportedVersions . indexOf ( schema . openapi ) === - 1 ) {
105
- throw ono . syntax (
106
- `Unsupported OpenAPI version: ${ schema . openapi } . ` +
107
- `Swagger Parser only supports versions ${ supportedVersions . join ( ", " ) } `
108
- ) ;
79
+ else if ( typeof schema . info . version === "number" ) {
80
+ // This is a very common mistake, so give a helpful error message
81
+ throw ono . syntax ( 'API version number must be a string (e.g. "1.0.0") not a number.' ) ;
82
+ }
83
+ else if ( supportedVersions . indexOf ( schema . openapi ) === - 1 ) {
84
+ throw ono . syntax (
85
+ `Unsupported OpenAPI version: ${ schema . openapi } . ` +
86
+ `Swagger Parser only supports versions ${ supportedVersions . join ( ", " ) } `
87
+ ) ;
88
+ }
89
+
90
+ // This is an OpenAPI v3 schema, check if the "servers" have any relative paths and
91
+ // fix them if the content was pulled from a web resource
92
+ util . fixOasRelativeServers ( schema , args . path ) ;
109
93
}
110
94
111
- // This is an OpenAPI v3 schema, check if the "servers" have any relative paths and
112
- // fix them if the content was pulled from a web resource
113
- util . fixOasRelativeServers ( schema , args . path ) ;
95
+ // Looks good!
96
+ return maybe ( args . callback , Promise . resolve ( schema ) ) ;
97
+ }
98
+ catch ( err ) {
99
+ return maybe ( args . callback , Promise . reject ( err ) ) ;
114
100
}
115
-
116
- // Looks good!
117
- return maybe ( args . callback , Promise . resolve ( schema ) ) ;
118
- }
119
- catch ( err ) {
120
- return maybe ( args . callback , Promise . reject ( err ) ) ;
121
101
}
122
- } ;
123
-
124
- /**
125
- * Parses, dereferences, and validates the given Swagger API.
126
- * Depending on the options, validation can include JSON Schema validation and/or Swagger Spec validation.
127
- *
128
- * @param {string } [path] - The file path or URL of the JSON schema
129
- * @param {object } [api] - The Swagger API object. This object will be used instead of reading from `path`.
130
- * @param {ParserOptions } [options] - Options that determine how the API is parsed, dereferenced, and validated
131
- * @param {Function } [callback] - An error-first callback. The second parameter is the parsed API object.
132
- * @returns {Promise } - The returned promise resolves with the parsed API object.
133
- */
134
- SwaggerParser . validate = function ( path , api , options , callback ) {
135
- let Class = this ; // eslint-disable-line consistent-this
136
- let instance = new Class ( ) ;
137
- return instance . validate . apply ( instance , arguments ) ;
138
- } ;
139
102
140
- /**
141
- * Parses, dereferences, and validates the given Swagger API.
142
- * Depending on the options, validation can include JSON Schema validation and/or Swagger Spec validation.
143
- *
144
- * @param {string } [path] - The file path or URL of the JSON schema
145
- * @param {object } [api] - The Swagger API object. This object will be used instead of reading from `path`.
146
- * @param {ParserOptions } [options] - Options that determine how the API is parsed, dereferenced, and validated
147
- * @param {Function } [callback] - An error-first callback. The second parameter is the parsed API object.
148
- * @returns {Promise } - The returned promise resolves with the parsed API object.
149
- */
150
- SwaggerParser . prototype . validate = async function ( path , api , options , callback ) {
151
- let me = this ;
152
- let args = normalizeArgs ( arguments ) ;
153
- args . options = new Options ( args . options ) ;
154
-
155
- // ZSchema doesn't support circular objects, so don't dereference circular $refs yet
156
- // (see https://github.com/zaggino/z-schema/issues/137)
157
- let circular$RefOption = args . options . dereference . circular ;
158
- args . options . validate . schema && ( args . options . dereference . circular = "ignore" ) ;
159
-
160
- try {
161
- await this . dereference ( args . path , args . schema , args . options ) ;
162
-
163
- // Restore the original options, now that we're done dereferencing
164
- args . options . dereference . circular = circular$RefOption ;
165
-
166
- if ( args . options . validate . schema ) {
167
- // Validate the API against the Swagger schema
168
- // NOTE: This is safe to do, because we haven't dereferenced circular $refs yet
169
- validateSchema ( me . api ) ;
170
-
171
- if ( me . $refs . circular ) {
172
- if ( circular$RefOption === true ) {
173
- // The API has circular references,
174
- // so we need to do a second-pass to fully-dereference it
175
- dereference ( me , args . options ) ;
176
- }
177
- else if ( circular$RefOption === false ) {
178
- // The API has circular references, and they're not allowed, so throw an error
179
- throw ono . reference ( "The API contains circular references" ) ;
103
+ /**
104
+ * Parses, dereferences, and validates the given Swagger API.
105
+ * Depending on the options, validation can include JSON Schema validation and/or Swagger Spec validation.
106
+ *
107
+ * @param {string } [path] - The file path or URL of the JSON schema
108
+ * @param {object } [api] - The Swagger API object. This object will be used instead of reading from `path`.
109
+ * @param {ParserOptions } [options] - Options that determine how the API is parsed, dereferenced, and validated
110
+ * @param {Function } [callback] - An error-first callback. The second parameter is the parsed API object.
111
+ * @returns {Promise } - The returned promise resolves with the parsed API object.
112
+ */
113
+ async validate ( path , api , options , callback ) {
114
+ let me = this ;
115
+ let args = normalizeArgs ( arguments ) ;
116
+ args . options = new Options ( args . options ) ;
117
+
118
+ // ZSchema doesn't support circular objects, so don't dereference circular $refs yet
119
+ // (see https://github.com/zaggino/z-schema/issues/137)
120
+ let circular$RefOption = args . options . dereference . circular ;
121
+ args . options . validate . schema && ( args . options . dereference . circular = "ignore" ) ;
122
+
123
+ try {
124
+ await this . dereference ( args . path , args . schema , args . options ) ;
125
+
126
+ // Restore the original options, now that we're done dereferencing
127
+ args . options . dereference . circular = circular$RefOption ;
128
+
129
+ if ( args . options . validate . schema ) {
130
+ // Validate the API against the Swagger schema
131
+ // NOTE: This is safe to do, because we haven't dereferenced circular $refs yet
132
+ validateSchema ( me . api ) ;
133
+
134
+ if ( me . $refs . circular ) {
135
+ if ( circular$RefOption === true ) {
136
+ // The API has circular references,
137
+ // so we need to do a second-pass to fully-dereference it
138
+ dereference ( me , args . options ) ;
139
+ }
140
+ else if ( circular$RefOption === false ) {
141
+ // The API has circular references, and they're not allowed, so throw an error
142
+ throw ono . reference ( "The API contains circular references" ) ;
143
+ }
180
144
}
181
145
}
182
- }
183
146
184
- if ( args . options . validate . spec ) {
185
- // Validate the API against the Swagger spec
186
- validateSpec ( me . api ) ;
187
- }
147
+ if ( args . options . validate . spec ) {
148
+ // Validate the API against the Swagger spec
149
+ validateSpec ( me . api ) ;
150
+ }
188
151
189
- return maybe ( args . callback , Promise . resolve ( me . schema ) ) ;
152
+ return maybe ( args . callback , Promise . resolve ( me . schema ) ) ;
153
+ }
154
+ catch ( err ) {
155
+ return maybe ( args . callback , Promise . reject ( err ) ) ;
156
+ }
190
157
}
191
- catch ( err ) {
192
- return maybe ( args . callback , Promise . reject ( err ) ) ;
158
+ }
159
+
160
+
161
+ /**
162
+ * Alias {@link $RefParser#schema} as {@link SwaggerParser#api}
163
+ */
164
+ Object . defineProperty ( SwaggerParser . prototype , "api" , {
165
+ configurable : true ,
166
+ enumerable : true ,
167
+ get ( ) {
168
+ return this . schema ;
193
169
}
194
- } ;
170
+ } ) ;
195
171
196
172
/**
197
173
* The Swagger object
198
174
* https://github.com/OAI/OpenAPI-Specification/blob/master/versions/2.0.md#swagger-object
199
175
*
200
176
* @typedef {{swagger: string, info: {}, paths: {}} } SwaggerObject
201
177
*/
178
+
179
+ const defaultInstance = new SwaggerParser ( ) ;
180
+ const defaultExport = SwaggerParser ;
181
+
182
+ defaultExport . validate = ( ...args ) => { return defaultInstance . validate ( ...args ) ; } ;
183
+ defaultExport . dereference = ( ...args ) => { return defaultInstance . dereference ( ...args ) ; } ;
184
+ defaultExport . bundle = ( ...args ) => { return defaultInstance . bundle ( ...args ) ; } ;
185
+ defaultExport . parse = ( ...args ) => { return defaultInstance . parse ( ...args ) ; } ;
186
+ defaultExport . resolve = ( ...args ) => { return defaultInstance . resolve ( ...args ) ; } ;
187
+ defaultExport . default = defaultExport ;
188
+ defaultExport . SwaggerParser = defaultExport ;
189
+
190
+ module . exports = defaultExport ;
0 commit comments