Socket
Socket
Sign inDemoInstall

swagger-endpoint-validator

Package Overview
Dependencies
212
Maintainers
5
Versions
15
Alerts
File Explorer

Advanced tools

Install Socket

Detect and block malicious and high-risk dependencies

Install

Comparing version 2.0.0 to 2.0.1

1

index.js

@@ -19,2 +19,3 @@ const debug = require('debug')('swagger-endpoint-validator');

* @param {boolean} [options.validateResponses=true] - true to validate the responses.
* @param {string|boolean} [options.validateFormats='fast'] - specifies the strictness of validation of string formats (one of 'fast', 'full' or false).
* @param {string} [options.validationEndpoint=null] - endpoint to do schemas validation agains the OpenAPI schema.

@@ -21,0 +22,0 @@ * @param {string} options.format - format of the OpenAPI specification documentation.

5

lib/errors.js
const util = require('util');
function SwaggerValidator(type, message) {
function SwaggerValidator(type, message, status) {
Error.captureStackTrace(this, this.constructor);

@@ -8,2 +8,3 @@ this.name = this.constructor.name;

this.message = message;
this.status = status;
}

@@ -13,5 +14,5 @@

const errorFactory = type => message => new SwaggerValidator(type, message);
const errorFactory = type => (message, status = 500) => new SwaggerValidator(type, message, status);
module.exports = errorFactory;

@@ -23,8 +23,11 @@ const debug = require('debug')('swagger-endpoint-validator:options');

const selectedFormat = options.format || SUPPORTED_FORMATS.YAML;
const normalizedOptions = {
validateRequests: options.validateRequests || true,
validateResponses: options.validateResponses || true,
validateRequests: options.validateRequests !== undefined ? options.validateRequests : true,
validateResponses: options.validateResponses !== undefined ? options.validateResponses : true,
validationEndpoint: options.validationEndpoint || null,
validateFormats: options.validateFormats !== undefined ? options.validateFormats : 'fast',
format: options.format || SUPPORTED_FORMATS.YAML,
[options.format]: formatOptions[options.format],
[options.format]: formatOptions[selectedFormat],
};

@@ -31,0 +34,0 @@

@@ -25,3 +25,3 @@ const debug = require('debug')('swagger-endpoint-validator:openapi-spec');

debug(`Converting specification from Swagger v2 to OpenAPI v3: ${JSON.stringify(doc)}`);
debug('Converting specification from Swagger v2 to OpenAPI v3...');
// swagger2openapi does the conversion between OpenAPI 2.0 and OpenAPI 3.0, but it has a small error:

@@ -39,3 +39,3 @@ // It doesn't add 'type: object' to the definitions.

const conversion = await apiConverter.convertObj(modifiedDoc, {});
debug(`Specification converted to OpenAPI v3: ${JSON.stringify(conversion.spec)}`);
debug('Specification converted to OpenAPI v3!');

@@ -55,3 +55,3 @@ return conversion.openapi;

const openapi = await Enforcer(doc);
debug(`Specification dereferenced and validated!: ${JSON.stringify(openapi)}`);
debug('Specification dereferenced and validated!');

@@ -58,0 +58,0 @@ return { doc, openapi };

@@ -19,3 +19,3 @@ const debug = require('debug')('swagger-endpoint-validator:validation-endpoint');

if (result.error) {
res.status(500).json(result.error);
res.status(400).json(result.error);
} else {

@@ -22,0 +22,0 @@ res.sendStatus(200);

@@ -26,2 +26,4 @@ const debug = require('debug')('swagger-endpoint-validator:validator');

validateResponses: options.validateResponses,
validateFormats: options.validateFormats,
ignorePaths: options.validationEndpoint ? new RegExp(`.*${options.validationEndpoint}$`, 'i') : null,
}).install(app);

@@ -52,8 +54,18 @@

fixture,
input,
request,
method,
} = body;
if (!endpoint) {
throw SwaggerValidatorError('Required \'endpoint\' missing in requestBody', 400);
}
if (!method) {
throw SwaggerValidatorError('Required \'method\' missing in requestBody', 400);
}
if (!fixture) {
throw SwaggerValidatorError('Required \'fixture\' missing in requestBody', 400);
}
let result;
if (input) {
if (request) {
result = openAPISpec.request({

@@ -67,7 +79,7 @@ method,

if (!path) {
throw SwaggerValidatorError(`Path ${endpoint} not found in the specification`);
throw SwaggerValidatorError(`endpoint '${endpoint}' not found in the specification`);
}
const operation = path[method];
const operation = path[method.toLowerCase()];
if (!operation) {
throw SwaggerValidatorError(`Method ${method} for path ${endpoint} not found in the specification`);
throw SwaggerValidatorError(`method '${method.toLowerCase()}' for endpoint '${endpoint}' not found in the specification`);
}

@@ -74,0 +86,0 @@ result = operation.response(200, fixture);

{
"name": "swagger-endpoint-validator",
"version": "2.0.0",
"version": "2.0.1",
"description": "A validator of API endpoints to check that input and output match with the swagger specification for the API",

@@ -38,3 +38,2 @@ "main": "index.js",

"swagger-jsdoc": "^4.0.0",
"swagger-model-validator": "^3.0.18",
"swagger-ui-express": "^4.1.4",

@@ -41,0 +40,0 @@ "swagger2openapi": "^6.0.2"

@@ -18,6 +18,6 @@

### init(app: ExpressApp, validatorOptions: ConfigFile, format: String)
### init(app: ExpressApp, options: ConfigFile)
```js
validator.init(app, validatorOptions, format);
validator.init(app, options);
```

@@ -28,307 +28,6 @@

- `app` is the Express app instance.
- `format` is an string to choose the format we want to create the swagger docs: `jsdoc` or `yaml`. Default `jsdoc`.
- `validatorOptions` is a configuration object that has different format depending on `format`:
- `options` is the configuration object used by the validator.
**`validatorOptions` for _jsdoc_**
## TO DO!
```js
const validatorOptions = {
swaggerDefinition: {
info: {
description: 'Documentation for Service API',
title: 'Service API',
version: '1.0.0',
contact: { email: 'your_email@guidesmiths.com' },
},
host: 'localhost:5000',
basePath: '/',
produces: ['application/json'],
schemes: ['http'],
securityDefinitions: {
JWT: {
type: 'apiKey',
in: 'header',
name: 'Authorization',
description: '',
},
},
},
basedir: process.cwd(), // app absolute path
files: ['./test/**/**.js'], // path to the API handle folder, related to basedir
route: {
url: '/test/docs/api',
docs: '/test/docs/api.json',
},
};
```
**`validatorOptions` for _yaml_**
```js
const validatorOptions = {
swaggerDefinition: {
info: {
description: 'Documentation for Service API',
title: 'Service API',
version: '1.0.0',
contact: { email: 'your_email@guidesmiths.com' },
},
basePath: '/',
},
apis: ['./test/**/**.js'], // paths to the API files
url: '/test/docs/api', // optional path to serve the API documentation
};
```
### validateAPIInput(input: Object, request: RequestObject)
```js
validator.validateAPIInput(input, request);
```
where:
- `input` is the payload to be validated.
- `request` is request object.
It will use the configuration used in the initialization to look for the endpoint and the schema to validate.
**JSDOC Example**
```js
/**
* @typedef Input
* @property {string} name.required
*/
/**
* @typedef Output
* @property {string} name.required
* @property {string} result.required
*/
/**
* @route GET /test-invalid-output
* @summary Create a new group
* @group test - Everything about tests
* @param {Input.model} body.body.required
* @returns {Output.model} 200 - Successful operation
* @returns {Error.model} <any> - Error message
* @security JWT
*/
app.get('/test-invalid-input', (req, res) => {
try {
validator.validateAPIInput({}, req);
} catch (error) {
res.status(404).json({ error });
}
});
```
**YAML Example**
```js
/**
* @swagger
* /test-invalid-input:
* post:
* description: Test POST /test-invalid-input
* tags: [Test]
* produces:
* - application/json
* parameters:
* - name: body
* description: Input payload
* required: true
* type: object
* schema:
* - $ref: '#/definitions/Input'
* responses:
* 200:
* description: successful operation
*/
app.post('/test-invalid-input', (req, res) => {
try {
const result = validator.validateAPIInput({}, req);
res.status(200).json(result);
} catch (error) {
res.status(404).json({ error });
}
});
```
### validateAPIOutput(output: Object, request: RequestObject)
```js
validator.validateAPIOutput(output, request);
```
where:
- `output` is the payload to be validated.
- `request` is request object.
It will use the configuration used in the initialization to look for the endpoint and the schema to validate.
**JSDOC Example**
```js
/**
* @typedef Input
* @property {string} name.required
*/
/**
* @typedef Output
* @property {string} name.required
* @property {string} result.required
*/
/**
* @route GET /test-invalid-output
* @summary Create a new group
* @group test - Everything about tests
* @param {Input.model} body.body.required
* @returns {Output.model} 200 - Successful operation
* @returns {Error.model} <any> - Error message
* @security JWT
*/
app.get('/test-invalid-output', (req, res) => {
const validInputModel = { name: 'Name is required' };
try {
validator.validateAPIInput(validInputModel, req);
validator.validateAPIOutput({}, req);
} catch (error) {
res.status(404).json({ error });
}
});
```
**YAML Example**
```js
/**
* @swagger
* /test-invalid-output:
* get:
* description: Test GET /test-invalid-output
* tags: [Test]
* produces:
* - application/json
* responses:
* 200:
* description: successful operation
* schema:
* $ref: '#/definitions/Output'
*/
app.get('/test-invalid-output', (req, res) => {
try {
const result = validator.validateAPIOutput({}, req);
res.status(200).json(result);
} catch (error) {
res.status(404).json({ error });
}
});
```
### Example of a valid request with the validator
**JSDOC**
```js
/**
* @typedef Input
* @property {string} name.required
*/
/**
* @typedef Output
* @property {string} name.required
* @property {string} result.required
*/
/**
* @route GET /test-valid
* @summary Create a new group
* @group test - Everything about tests
* @param {Input.model} body.body.required
* @returns {Output.model} 200 - Successful operation
* @returns {Error.model} <any> - Error message
* @security JWT
*/
app.get('/test-valid', (req, res) => {
const validInputModel = { name: 'Name is required' };
const validOutputModel = { name: 'Name is required', result: 'Valid result' };
validator.validateAPIInput(validInputModel, req);
validator.validateAPIOutput(validOutputModel, req);
res.status(200).json({ success: true });
});
```
**YAML**
```js
/**
* @swagger
* /test-valid-input:
* post:
* description: Test POST /test-valid-input
* tags: [Test]
* produces:
* - application/json
* parameters:
* - name: body
* description: Input payload
* required: true
* type: object
* schema:
* - $ref: '#/definitions/Input'
* responses:
* 200:
* description: successful operation
*/
app.post('/test-valid-input', (req, res) => {
const validInputModel = { name: 'Name is required' };
try {
const result = validator.validateAPIInput(validInputModel, req);
res.status(200).json(result);
} catch (error) {
res.status(404).json({ error });
}
});
/**
* @swagger
* /test-valid-output:
* get:
* description: Test GET /test-valid-output
* tags: [Test]
* produces:
* - application/json
* parameters:
* - name: body
* description: Input payload
* required: true
* type: object
* schema:
* - $ref: '#/definitions/Input'
* responses:
* 200:
* description: successful operation
* schema:
* $ref: '#/definitions/Output'
*/
app.get('/test-valid-output', (req, res) => {
const validInputModel = { name: 'Name is required' };
const validOutputModel = { name: 'Name is required', result: 'Valid result' };
try {
validator.validateAPIInput(validInputModel, req);
const result = validator.validateAPIOutput(validOutputModel, req);
res.status(200).json(result);
} catch (error) {
res.status(404).json({ error });
}
});
```
Improve this doc.
SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc