swagger-spec-validator
Advanced tools
Comparing version 2.0.0 to 3.0.0
@@ -12,7 +12,7 @@ #!/usr/bin/env node | ||
const Yargs = require('yargs/yargs'); | ||
const arrayUniq = require('array-uniq'); | ||
const assign = require('object-assign'); | ||
const url = require('url'); | ||
const packageJson = require('../package.json'); | ||
const swaggerSpecValidator = require('..'); | ||
const url = require('url'); | ||
@@ -38,4 +38,4 @@ function parseHeader(line) { | ||
.map(parseHeader) | ||
.reduce((headerObj, header) => { | ||
headerObj[header[0]] = header[1]; | ||
.reduce((headerObj, [headerName, headerVal]) => { | ||
headerObj[headerName] = headerVal; | ||
return headerObj; | ||
@@ -55,5 +55,5 @@ }, {}); | ||
try { | ||
yargs.parse(args, function() { | ||
yargs.parse(args, function(...cbargs) { | ||
called = true; | ||
return callback.apply(this, arguments); | ||
return callback.apply(this, cbargs); | ||
}); | ||
@@ -105,4 +105,4 @@ } catch (err) { | ||
if (options.verbosity >= 0) { | ||
const messagesWithPath = | ||
messages.map((message) => `${specPath}: ${message}`); | ||
const messagesWithPath | ||
= messages.map((message) => `${specPath}: ${message}`); | ||
options.out.write(`${messagesWithPath.join('\n')}\n`); | ||
@@ -178,4 +178,4 @@ } | ||
args = []; | ||
} else if (typeof args !== 'object' || | ||
Math.floor(args.length) !== args.length) { | ||
} else if (typeof args !== 'object' | ||
|| Math.floor(args.length) !== args.length) { | ||
throw new TypeError('args must be Array-like'); | ||
@@ -282,3 +282,3 @@ } else if (args.length < 2 && args.length !== 0) { | ||
} else if (specPaths.length > 1) { | ||
specPaths = arrayUniq(specPaths); | ||
specPaths = [...new Set(specPaths)]; | ||
} | ||
@@ -285,0 +285,0 @@ |
# Change Log | ||
## [2.0.0](https://github.com/kevinoid/swagger-spec-validator/tree/2.0.0) (2018-04-19) | ||
[Full Changelog](https://github.com/kevinoid/swagger-spec-validator/compare/v1.0.1...2.0.0) | ||
## [v3.0.0](https://github.com/kevinoid/swagger-spec-validator/tree/v3.0.0) (2018-06-29) | ||
[Full Changelog](https://github.com/kevinoid/swagger-spec-validator/compare/v2.0.0...v3.0.0) | ||
- **BREAKING** Drop support for Node < 6. | ||
- Dependency version updates. | ||
- Drop unnecessary dependencies. | ||
- Code style improvements. | ||
## [v2.0.0](https://github.com/kevinoid/swagger-spec-validator/tree/v2.0.0) (2018-04-19) | ||
[Full Changelog](https://github.com/kevinoid/swagger-spec-validator/compare/v1.0.1...v2.0.0) | ||
- **Major:** Drop support for Node v0.12. Require Node v4 or later. | ||
@@ -12,9 +20,9 @@ - Replace DigiCert intermediate+root certificates with GoDaddy, which is now | ||
## [1.0.1](https://github.com/kevinoid/swagger-spec-validator/tree/1.0.1) (2017-05-07) | ||
[Full Changelog](https://github.com/kevinoid/swagger-spec-validator/compare/1.0.0...1.0.1) | ||
## [v1.0.1](https://github.com/kevinoid/swagger-spec-validator/tree/v1.0.1) (2017-05-07) | ||
[Full Changelog](https://github.com/kevinoid/swagger-spec-validator/compare/v1.0.0...v1.0.1) | ||
- Include DigiCert Global Root CA in package to fix SSL validation on Debian. | ||
## [1.0.0](https://github.com/kevinoid/swagger-spec-validator/tree/1.0.0) (2017-03-16) | ||
[Full Changelog](https://github.com/kevinoid/swagger-spec-validator/compare/0.1.2...1.0.0) | ||
## [v1.0.0](https://github.com/kevinoid/swagger-spec-validator/tree/v1.0.0) (2017-03-16) | ||
[Full Changelog](https://github.com/kevinoid/swagger-spec-validator/compare/v0.1.2...v1.0.0) | ||
@@ -24,4 +32,4 @@ - **No API Changes** Change to v1.0.0 is only a declaration of stability. | ||
## [0.1.2](https://github.com/kevinoid/swagger-spec-validator/tree/0.1.2) (2017-03-03) | ||
[Full Changelog](https://github.com/kevinoid/swagger-spec-validator/compare/v0.1.2...0.1.2) | ||
## [v0.1.2](https://github.com/kevinoid/swagger-spec-validator/tree/v0.1.2) (2017-03-03) | ||
[Full Changelog](https://github.com/kevinoid/swagger-spec-validator/compare/v0.1.2...v0.1.2) | ||
@@ -28,0 +36,0 @@ ## [v0.1.2](https://github.com/kevinoid/swagger-spec-validator/tree/v0.1.2) (2017-03-03) |
231
index.js
@@ -12,3 +12,2 @@ /** | ||
const https = require('https'); | ||
const packageJson = require('./package.json'); | ||
const path = require('path'); | ||
@@ -19,2 +18,4 @@ const pify = require('pify'); | ||
const packageJson = require('./package.json'); | ||
const readFileP = pify(fs.readFile); | ||
@@ -37,4 +38,4 @@ const readdirP = pify(fs.readdir); | ||
Accept: 'application/json', | ||
'User-Agent': `${packageJson.name}/${packageJson.version} ` + | ||
`Node.js/${process.version.slice(1)}` | ||
'User-Agent': `${packageJson.name}/${packageJson.version} ` | ||
+ `Node.js/${process.version.slice(1)}` | ||
}); | ||
@@ -56,14 +57,14 @@ swaggerSpecValidator.DEFAULT_HEADERS = DEFAULT_HEADERS; | ||
// eslint-disable-next-line no-underscore-dangle | ||
swaggerSpecValidator._getSwaggerIoAgent = | ||
function getSwaggerIoAgent() { | ||
if (!swaggerIoHttpsAgent) { | ||
const certsPath = path.join(__dirname, 'certs'); | ||
swaggerIoHttpsAgent = readdirP(certsPath) | ||
.then((certNames) => Promise.all( | ||
certNames.map((certName) => { | ||
const certPath = path.join(certsPath, certName); | ||
return readFileP(certPath, {encoding: 'utf8'}); | ||
}) | ||
)) | ||
.then((certs) => { | ||
swaggerSpecValidator._getSwaggerIoAgent | ||
= function getSwaggerIoAgent() { | ||
if (!swaggerIoHttpsAgent) { | ||
const certsPath = path.join(__dirname, 'certs'); | ||
swaggerIoHttpsAgent = readdirP(certsPath) | ||
.then((certNames) => Promise.all( | ||
certNames.map((certName) => { | ||
const certPath = path.join(certsPath, certName); | ||
return readFileP(certPath, {encoding: 'utf8'}); | ||
}) | ||
)) | ||
.then((certs) => { | ||
// Note: Using undocumented API to use both root and loaded certs. | ||
@@ -75,15 +76,15 @@ // Specifying options.ca skips root certs, which could cause cert | ||
// This is why the DigiCert Root CA file is in the package. | ||
const secureContext = tls.createSecureContext(); | ||
certs.forEach((cert) => { | ||
secureContext.context.addCACert(cert); | ||
const secureContext = tls.createSecureContext(); | ||
certs.forEach((cert) => { | ||
secureContext.context.addCACert(cert); | ||
}); | ||
return new https.Agent({ | ||
keepAlive: true, | ||
secureContext | ||
}); | ||
}); | ||
return new https.Agent({ | ||
keepAlive: true, | ||
secureContext | ||
}); | ||
}); | ||
} | ||
} | ||
return swaggerIoHttpsAgent; | ||
}; | ||
return swaggerIoHttpsAgent; | ||
}; | ||
@@ -94,6 +95,5 @@ /** Combines HTTP headers objects. | ||
*/ | ||
function combineHeaders() { | ||
function combineHeaders(...args) { | ||
const combinedLower = {}; | ||
const combined = {}; | ||
const args = Array.prototype.slice.call(arguments); | ||
args.reverse(); | ||
@@ -118,5 +118,5 @@ args.forEach((headers) => { | ||
function requestJson(options, callback) { | ||
const proto = options.protocol === 'https:' ? https : | ||
options.protocol === 'http:' ? http : | ||
null; | ||
const proto = options.protocol === 'https:' ? https | ||
: options.protocol === 'http:' ? http | ||
: null; | ||
if (!proto) { | ||
@@ -167,3 +167,3 @@ callback( | ||
const body = options.body; | ||
const {body} = options; | ||
if (typeof body === 'string' || Buffer.isBuffer(body)) { | ||
@@ -205,77 +205,77 @@ req.end(body); | ||
*/ | ||
swaggerSpecValidator.validate = | ||
function validate(spec, options, callback) { | ||
if (!callback && typeof options === 'function') { | ||
callback = options; | ||
options = null; | ||
} | ||
swaggerSpecValidator.validate | ||
= function validate(spec, options, callback) { | ||
if (!callback && typeof options === 'function') { | ||
callback = options; | ||
options = null; | ||
} | ||
if (!callback) { | ||
return new Promise((resolve, reject) => { | ||
validate(spec, options, (err, result) => { | ||
if (err) { reject(err); } else { resolve(result); } | ||
if (!callback) { | ||
return new Promise((resolve, reject) => { | ||
validate(spec, options, (err, result) => { | ||
if (err) { reject(err); } else { resolve(result); } | ||
}); | ||
}); | ||
}); | ||
} | ||
} | ||
if (typeof callback !== 'function') { | ||
throw new TypeError('callback must be a function'); | ||
} | ||
try { | ||
if (spec === undefined || | ||
spec === null || | ||
(typeof spec !== 'string' && | ||
!Buffer.isBuffer(spec) && | ||
typeof spec.pipe !== 'function')) { | ||
throw new TypeError('spec must be a string, Buffer, or Readable'); | ||
if (typeof callback !== 'function') { | ||
throw new TypeError('callback must be a function'); | ||
} | ||
if (options !== undefined && typeof options !== 'object') { | ||
throw new TypeError('options must be an object'); | ||
try { | ||
if (spec === undefined | ||
|| spec === null | ||
|| (typeof spec !== 'string' | ||
&& !Buffer.isBuffer(spec) | ||
&& typeof spec.pipe !== 'function')) { | ||
throw new TypeError('spec must be a string, Buffer, or Readable'); | ||
} | ||
if (options !== undefined && typeof options !== 'object') { | ||
throw new TypeError('options must be an object'); | ||
} | ||
} catch (err) { | ||
process.nextTick(() => { | ||
callback(err); | ||
}); | ||
return undefined; | ||
} | ||
} catch (err) { | ||
process.nextTick(() => { | ||
callback(err); | ||
}); | ||
return undefined; | ||
} | ||
const reqOpts = url.parse(DEFAULT_URL); | ||
reqOpts.method = 'POST'; | ||
assign(reqOpts, options && options.request); | ||
reqOpts.headers = combineHeaders(DEFAULT_HEADERS, reqOpts.headers); | ||
reqOpts.body = spec; | ||
const reqOpts = url.parse(DEFAULT_URL); | ||
reqOpts.method = 'POST'; | ||
assign(reqOpts, options && options.request); | ||
reqOpts.headers = combineHeaders(DEFAULT_HEADERS, reqOpts.headers); | ||
reqOpts.body = spec; | ||
let calledBack = false; | ||
function callbackOnce(err) { | ||
if (!calledBack) { | ||
calledBack = true; | ||
callback.apply(this, arguments); | ||
let calledBack = false; | ||
function callbackOnce(...args) { | ||
if (!calledBack) { | ||
calledBack = true; | ||
callback.apply(this, args); | ||
} | ||
} | ||
} | ||
if (reqOpts.hostname === 'online.swagger.io' && | ||
!hasOwnProperty.call(reqOpts, 'agent')) { | ||
if (typeof spec.pipe === 'function') { | ||
if (reqOpts.hostname === 'online.swagger.io' | ||
&& !hasOwnProperty.call(reqOpts, 'agent')) { | ||
if (typeof spec.pipe === 'function') { | ||
// Stream can emit an error before Agent is loaded. Handle this. | ||
spec.on('error', callbackOnce); | ||
spec.on('error', callbackOnce); | ||
} | ||
// eslint-disable-next-line no-underscore-dangle | ||
swaggerSpecValidator._getSwaggerIoAgent() | ||
.then((agent) => { | ||
if (!calledBack) { | ||
reqOpts.agent = agent; | ||
requestJson(reqOpts, callbackOnce); | ||
} | ||
}) | ||
.catch(callbackOnce); | ||
} else { | ||
requestJson(reqOpts, callback); | ||
} | ||
// eslint-disable-next-line no-underscore-dangle | ||
swaggerSpecValidator._getSwaggerIoAgent() | ||
.then((agent) => { | ||
if (!calledBack) { | ||
reqOpts.agent = agent; | ||
requestJson(reqOpts, callbackOnce); | ||
} | ||
}) | ||
.catch(callbackOnce); | ||
} else { | ||
requestJson(reqOpts, callback); | ||
} | ||
return undefined; | ||
}; | ||
return undefined; | ||
}; | ||
/** Validates an OpenAPI/Swagger API specification file. | ||
@@ -293,29 +293,30 @@ * | ||
*/ | ||
swaggerSpecValidator.validateFile = | ||
function validateFile(specPath, options, callback) { | ||
if (!callback && typeof options === 'function') { | ||
callback = options; | ||
options = null; | ||
} | ||
swaggerSpecValidator.validateFile | ||
= function validateFile(specPath, options, callback) { | ||
if (!callback && typeof options === 'function') { | ||
callback = options; | ||
options = null; | ||
} | ||
const headers = options && options.request && options.request.headers; | ||
const hasContentType = headers && | ||
Object.keys(headers).some((name) => name.toLowerCase() === 'content-type'); | ||
if (!hasContentType) { | ||
const headers = options && options.request && options.request.headers; | ||
const hasContentType = headers | ||
&& Object.keys(headers) | ||
.some((name) => name.toLowerCase() === 'content-type'); | ||
if (!hasContentType) { | ||
// Server ignores Content-Type, so not worth depending on a Media Type db. | ||
const contentType = /\.json$/i.test(specPath) ? 'application/json' : | ||
/\.ya?ml$/i.test(specPath) ? 'text/x-yaml' : | ||
null; | ||
if (contentType) { | ||
options = assign({}, options); | ||
options.request = assign({}, options.request); | ||
options.request.headers = assign({}, options.request.headers); | ||
options.request.headers['Content-Type'] = contentType; | ||
const contentType = /\.json$/i.test(specPath) ? 'application/json' | ||
: /\.ya?ml$/i.test(specPath) ? 'text/x-yaml' | ||
: null; | ||
if (contentType) { | ||
options = assign({}, options); | ||
options.request = assign({}, options.request); | ||
options.request.headers = assign({}, options.request.headers); | ||
options.request.headers['Content-Type'] = contentType; | ||
} | ||
} | ||
} | ||
const specStream = fs.createReadStream(specPath); | ||
return swaggerSpecValidator.validate(specStream, options, callback); | ||
}; | ||
const specStream = fs.createReadStream(specPath); | ||
return swaggerSpecValidator.validate(specStream, options, callback); | ||
}; | ||
module.exports = swaggerSpecValidator; |
{ | ||
"name": "swagger-spec-validator", | ||
"version": "2.0.0", | ||
"version": "3.0.0", | ||
"description": "Validate an OpenAPI/Swagger API specification using the swagger.io online validator.", | ||
@@ -34,3 +34,3 @@ "keywords": [ | ||
"postversion": "rimraf doc && git clone -b gh-pages -l -q . doc && npm run doc && git -C doc add . && git -C doc commit -n -m \"Docs for v$npm_package_version\"", | ||
"preversion": "depcheck --ignores eslint-plugin-import --ignore-dirs doc && david && git-branch-is master && travis-status -b master -c -wx && appveyor-status -b master -c -w -p kevinoid/swagger-spec-validator && istanbul check-coverage --statements 95 coverage/coverage.json", | ||
"preversion": "depcheck --ignores eslint-plugin-import,greenkeeper-lockfile --ignore-dirs doc && david -i eslint && git-branch-is master && travis-status -b master -c -wx && appveyor-status -b master -c -w -p kevinoid/swagger-spec-validator && istanbul check-coverage --statements 95 coverage/coverage.json", | ||
"test": "npm run lint && npm run test-unit", | ||
@@ -45,6 +45,5 @@ "test-cov": "npm run lint && npm run test-unit-cov", | ||
"dependencies": { | ||
"array-uniq": "^1.0.3", | ||
"object-assign": "^4.1.0", | ||
"pify": "^3.0.0", | ||
"yargs": "^11.0.0" | ||
"yargs": "^12.0.1" | ||
}, | ||
@@ -55,4 +54,5 @@ "devDependencies": { | ||
"eslint": "^4.6.1", | ||
"eslint-config-airbnb-base": "^12.0.0", | ||
"eslint-config-airbnb-base": "^13.0.0", | ||
"eslint-plugin-import": "^2.7.0", | ||
"greenkeeper-lockfile": "^1.15.1", | ||
"istanbul": "^0.4.1", | ||
@@ -62,12 +62,17 @@ "jsdoc": "^3.4.1", | ||
"nock": "^9.0.14", | ||
"nodecat": "^1.0.0", | ||
"nodecat": "^2.0.0", | ||
"proxyquire": "^2.0.0", | ||
"regexp.escape": "^1.0.2", | ||
"rimraf": "^2.2.0", | ||
"sinon": "^5.0.0" | ||
"sinon": "^6.0.0" | ||
}, | ||
"engines": { | ||
"node": ">=4", | ||
"node": ">=6", | ||
"npm": ">=1.3.7" | ||
}, | ||
"greenkeeper": { | ||
"ignore": [ | ||
"eslint" | ||
] | ||
}, | ||
"yargs": { | ||
@@ -74,0 +79,0 @@ "parse-numbers": false, |
3
32241
15
8
562
+ Addedcamelcase@5.3.1(transitive)
+ Addedfind-up@3.0.0(transitive)
+ Addedlocate-path@3.0.0(transitive)
+ Addedp-limit@2.3.0(transitive)
+ Addedp-locate@3.0.0(transitive)
+ Addedp-try@2.2.0(transitive)
+ Addedy18n@4.0.3(transitive)
+ Addedyargs@12.0.5(transitive)
+ Addedyargs-parser@11.1.1(transitive)
- Removedarray-uniq@^1.0.3
- Removedarray-uniq@1.0.3(transitive)
- Removedcamelcase@4.1.0(transitive)
- Removedfind-up@2.1.0(transitive)
- Removedlocate-path@2.0.0(transitive)
- Removedp-limit@1.3.0(transitive)
- Removedp-locate@2.0.0(transitive)
- Removedp-try@1.0.0(transitive)
- Removedy18n@3.2.2(transitive)
- Removedyargs@11.1.1(transitive)
- Removedyargs-parser@9.0.2(transitive)
Updatedyargs@^12.0.1