@dechamp/express-auto-route
Version:
An express auto route module which allows routes and middleware to be configured via config file.
133 lines (107 loc) • 3.71 kB
text/typescript
const path = require("path");
const joi = require("@hapi/joi");
const deref = require("json-schema-deref-sync");
const {sprintf} = require("sprintf-js");
import jsonSchemaValidator from "../../jsonSchema/jsonSchemaValidationService";
const MSG_SCHEMA_FAILED = "Failed json schema on %s, errors: %s";
export interface Schema {
query?: any;
body?: any;
params?: any;
}
export default class RouteRequestJsonSchemaValidator {
callback(req, res, next) {
const {config: {route}} = req;
if (!route.hasOwnProperty("requestJsonSchema")) {
return next();
}
try {
joi.assert(
route,
joi.object().keys({
requestJsonSchema: joi.object().keys({
query: joi.string(),
body: joi.string(),
params: joi.string(),
}).or("query", "body", "params"),
}).unknown(true),
);
const {query, body, params} = this.buildRequestJsonSchema(
route.requestJsonSchema,
);
if (params) {
const paramsError = this.validateParams(params, req);
if (paramsError) {
return next(sprintf(MSG_SCHEMA_FAILED, "params", paramsError).trim("\n"));
}
}
if (query) {
const queryError = this.validateQuery(query, req);
if (queryError) {
return next(sprintf(MSG_SCHEMA_FAILED, "query", queryError).trim("\n"));
}
}
if (body) {
const bodyError = this.validateBody(body, req);
if (bodyError) {
return next(sprintf(MSG_SCHEMA_FAILED, "body", bodyError).trim("\n"));
}
}
} catch (error) {
if (error.hasOwnProperty("details")) {
console.debug(
`Skipping route "${route.id}" due to ${error.details[0].message}`);
return next();
}
return next(error.message);
}
return next();
}
private validateParams(schema, req) {
debugger;
return jsonSchemaValidator(
schema,
req.params,
);
}
private validateQuery(schema, req) {
return jsonSchemaValidator(
schema,
req.query,
);
}
private validateBody(schema, req) {
return jsonSchemaValidator(
schema,
req.body,
);
}
private buildRequestJsonSchema(requestJsonSchema) {
const schema: Schema = {};
if (requestJsonSchema.hasOwnProperty("params")) {
const paramsSchema = path.join(
process.cwd(),
requestJsonSchema.params,
);
const paramsSchemaFromFile = require(paramsSchema);
schema.params = deref(paramsSchemaFromFile);
}
if (requestJsonSchema.hasOwnProperty("query")) {
const querySchema = path.join(
process.cwd(),
requestJsonSchema.query,
);
const querySchemaFromFile = require(querySchema);
schema.query = deref(querySchemaFromFile);
}
if (requestJsonSchema.hasOwnProperty("body")) {
const bodySchema = path.join(
process.cwd(),
requestJsonSchema.body,
);
const bodySchemaFromFile = require(bodySchema);
schema.body = deref(bodySchemaFromFile);
}
return schema;
}
}