-
Notifications
You must be signed in to change notification settings - Fork 0
/
index.ts
120 lines (111 loc) · 5.06 KB
/
index.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
import * as restify from 'restify';
import { ErrorVar, JsonSchema, MultiResult, validateMultiple as tv4_validateMultiple } from 'tv4';
import { toSentenceCase } from '@offscale/nodejs-utils';
import { GenericError } from '@offscale/custom-restify-errors';
import { IOrmReq } from '@offscale/orm-mw/interfaces';
import { CustomJsonError } from './interfaces.d';
export const has_body = (req: restify.Request, res: restify.Response, next: restify.Next) =>
next(req.body == null ? new GenericError({
name: 'ValidationError',
message: 'Body required',
statusCode: 400
}) : void 0);
export const jsonSchemaErrorParser = (body_is: MultiResult): CustomJsonError | undefined =>
body_is.valid ? void 0 : body_is.errors.length === 1 ? {
error: 'ValidationError',
error_message: body_is.errors[0].message
} : {
error: 'ValidationError',
error_message: 'JSON-Schema validation failed',
error_metadata: {
cls: 'tv4',
// @ts-ignore
errors: body_is['errors'].map((error: ErrorVar) =>
Object.assign({
code: error.code,
dataPath: error.dataPath,
message: error.message,
params: error.params,
schemaPath: error.schemaPath,
subErrors: error.subErrors,
}, process.env.hasOwnProperty('DEBUG_LEVEL')
&& parseInt(process.env['DEBUG_LEVEL'] as unknown as string, 10) > 2 ?
{ stack: error.stack } : {})
),
missing: body_is.missing,
valid: body_is.valid
}
};
export const mk_valid_body_mw = (json_schema: JsonSchema, to_res = true) =>
/*valid_body*/ (request: restify.Request, res: restify.Response, next: restify.Next) => {
const req = request as unknown as IOrmReq & restify.Request & { [key: string]: CustomJsonError | undefined };
const body_is = tv4_validateMultiple(req.body, json_schema);
if (!body_is.valid)
(error => to_res ? res.json(400, error) && next(false) : req['json_schema_error'] = error)(
jsonSchemaErrorParser(body_is)
);
else return next();
};
export const mk_valid_body_mw_ignore = (json_schema: JsonSchema, ignore: string[]) => {
return function valid_body(_req: restify.Request, res: restify.Response, next: restify.Next) {
const req = _req as typeof _req & { [key: string]: any };
if (!req['json_schema_error']) return next();
ignore.map(filter => {
switch (true) {
case req['json_schema_error'].error_message.substr(0, filter.length) === filter:
req['json_schema_error'].delete_me = true;
break;
case req['json_schema_error'].error_message === 'JSON-Schema validation failed':
req['json_schema_error'].error_metadata.errors =
req['json_schema_error'].error_metadata.errors.filter((error: Error) =>
error.message.substring(0, filter.length) !== filter
);
break;
default: /* tslint:disable:no-console */
console.warn('Unknown dataset received instead of json_schema_error');
}
}
);
if (req['json_schema_error'].delete_me
|| req['json_schema_error'].error_metadata
&& !req['json_schema_error'].error_metadata.errors.length)
delete req['json_schema_error'];
return next();
};
};
export const jsonSchemaNamedArrayOf = (json_schema: tv4.JsonSchema, type_name?: string,
type_plural?: string): tv4.JsonSchema => {
type_name = type_name || json_schema.title == null ? 'UnknownType' : json_schema.title.toString();
const upper_of_type = toSentenceCase(type_name);
const upper_of_types = toSentenceCase(type_plural || `${type_name}s`);
const lower_types = upper_of_types.toLocaleLowerCase();
return {
$schema: 'http://json-schema.org/draft-06/schema#',
$ref: `#/definitions/${upper_of_types}`,
definitions: {
[upper_of_types]: {
type: 'object',
additionalProperties: false,
properties: {
[lower_types]: {
type: 'array',
items: {
$ref: `#/definitions/${upper_of_type}`
}
}
},
required: [
lower_types
],
title: lower_types
},
[upper_of_type]: json_schema
}
};
};
export const remove_from_body = (keys: string[]) =>
(request: restify.Request, res: restify.Response, next: restify.Next) => {
const req = request as unknown as IOrmReq & restify.Request;
keys.map(key => req.body && req.body[key] ? delete req.body[key] : null);
return next();
};