anote-server-libs 0.3.4 → 0.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "anote-server-libs",
3
- "version": "0.3.4",
3
+ "version": "0.4.0",
4
4
  "description": "Helpers for express-TS servers",
5
5
  "scripts": {
6
6
  "test": "echo \"Error: no test specified\" && exit 1",
@@ -16,21 +16,21 @@
16
16
  "author": "Mathonet Gregoire",
17
17
  "license": "MIT",
18
18
  "dependencies": {
19
- "@types/memcached": "2.2.7",
20
- "@types/mssql": "8.1.1",
21
- "@types/pg": "8.6.5",
19
+ "ajv": "8.12.0",
22
20
  "memcached": "2.2.2",
23
- "mssql": "9.0.1",
24
- "pg": "8.8.0"
21
+ "mssql": "9.1.1",
22
+ "pg": "8.9.0"
25
23
  },
26
24
  "peerDependencies": {
27
25
  "express": "4.18.2",
28
- "jsonschema": "1.4.1",
29
26
  "winston": "3.8.2"
30
27
  },
31
28
  "devDependencies": {
32
- "@types/express": "4.17.14",
29
+ "@types/express": "4.17.16",
30
+ "@types/memcached": "2.2.7",
31
+ "@types/mssql": "8.1.2",
33
32
  "@types/node": "14.18.2",
34
- "typescript": "4.8.4"
33
+ "@types/pg": "8.6.6",
34
+ "typescript": "4.9.4"
35
35
  }
36
36
  }
@@ -1,30 +1,35 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.WithBody = void 0;
4
- const jsonschema_1 = require("jsonschema");
4
+ const ajv_1 = require("ajv");
5
5
  function WithBody(schema) {
6
- const validator = new jsonschema_1.Validator();
7
- validator.attributes.maxDigits = (instance, sc) => {
8
- if (typeof instance !== 'number')
9
- return undefined;
10
- if (typeof sc.maxDigits !== 'number' || Math.floor(sc.maxDigits) !== sc.maxDigits) {
11
- throw new jsonschema_1.SchemaError('"maxDigits" expects an integer', sc);
6
+ const ajv = new ajv_1.default();
7
+ ajv.addKeyword({
8
+ keyword: 'maxDigits',
9
+ type: 'number',
10
+ schemaType: 'integer',
11
+ code(cxt) {
12
+ const { data, schema } = cxt;
13
+ const op = (0, ajv_1._) `!==`;
14
+ const roundedData = Math.round(data * 10 ** schema) / (10 ** schema);
15
+ cxt.fail((0, ajv_1._) `${roundedData} ${op} ${data}`);
12
16
  }
13
- if (Math.round(instance * 10 ** sc.maxDigits) / (10 ** sc.maxDigits) !== instance) {
14
- return 'has more precision than ' + sc.maxDigits + ' digits';
15
- }
16
- return undefined;
17
- };
17
+ });
18
+ let validate = ajv.compile(schema);
18
19
  return function (_, __, descriptor) {
19
20
  if (typeof descriptor.value === 'function') {
20
21
  const previousMethod = descriptor.value;
21
22
  descriptor.value = function (req, res) {
22
23
  const keys = Object.getOwnPropertyNames(schema.properties);
24
+ let dynKey = false;
23
25
  keys.forEach(key => {
24
26
  if (typeof schema.properties[key] === 'string') {
25
27
  schema.properties[key] = this.config.app.endpointsSchemas[schema.properties[key]];
28
+ dynKey = true;
26
29
  }
27
30
  });
31
+ if (dynKey)
32
+ validate = ajv.compile(schema);
28
33
  if (req.method.toUpperCase() !== 'POST' && req.method.toUpperCase() !== 'PUT') {
29
34
  return previousMethod.call(this, req, res);
30
35
  }
@@ -37,8 +42,8 @@ function WithBody(schema) {
37
42
  });
38
43
  }
39
44
  else {
40
- const result = validator.validate(req.body, schema);
41
- if (result.valid) {
45
+ const valid = validate(req.body);
46
+ if (valid) {
42
47
  return previousMethod.call(this, req, res);
43
48
  }
44
49
  else {
@@ -46,7 +51,7 @@ function WithBody(schema) {
46
51
  error: {
47
52
  errorKey: 'client.body.missing',
48
53
  additionalInfo: 'client.extended.badPayload',
49
- detailedInfo: result.errors
54
+ detailedInfo: validate.errors
50
55
  }
51
56
  });
52
57
  }
@@ -1,29 +1,34 @@
1
1
  import {Request, Response} from 'express';
2
- import {SchemaError, Validator} from 'jsonschema';
2
+ import Ajv, {_} from 'ajv';
3
3
 
4
4
  export function WithBody(schema: any) {
5
- const validator = new Validator();
6
- validator.attributes.maxDigits = (instance, sc: any) => {
7
- if(typeof instance !== 'number') return undefined;
8
- if(typeof sc.maxDigits !== 'number' || Math.floor(sc.maxDigits) !== sc.maxDigits) {
9
- throw new SchemaError('"maxDigits" expects an integer', sc);
5
+ const ajv = new Ajv();
6
+ ajv.addKeyword({
7
+ keyword: 'maxDigits',
8
+ type: 'number',
9
+ schemaType: 'integer',
10
+ code(cxt: any) {
11
+ const {data, schema} = cxt;
12
+ const op = _`!==`;
13
+ const roundedData = Math.round(data * 10 ** schema) / (10 ** schema);
14
+ cxt.fail(_`${roundedData} ${op} ${data}`);
10
15
  }
11
- if(Math.round(instance * 10 ** sc.maxDigits) / (10 ** sc.maxDigits) !== instance) {
12
- return 'has more precision than ' + sc.maxDigits + ' digits';
13
- }
14
- return undefined;
15
- };
16
+ });
17
+ let validate = ajv.compile(schema);
16
18
 
17
19
  return function(_: any, __: string, descriptor: PropertyDescriptor) {
18
20
  if(typeof descriptor.value === 'function') {
19
21
  const previousMethod = descriptor.value;
20
22
  descriptor.value = function(this: any, req: Request, res: Response) {
21
23
  const keys = Object.getOwnPropertyNames(schema.properties);
24
+ let dynKey = false;
22
25
  keys.forEach(key => {
23
26
  if(typeof schema.properties[key] === 'string') {
24
27
  schema.properties[key] = this.config.app.endpointsSchemas[schema.properties[key]];
28
+ dynKey = true;
25
29
  }
26
30
  });
31
+ if(dynKey) validate = ajv.compile(schema);
27
32
  if(req.method.toUpperCase() !== 'POST' && req.method.toUpperCase() !== 'PUT') {
28
33
  return previousMethod.call(this, req, res);
29
34
  }
@@ -35,15 +40,15 @@ export function WithBody(schema: any) {
35
40
  }
36
41
  });
37
42
  } else {
38
- const result = validator.validate(req.body, schema);
39
- if(result.valid) {
43
+ const valid = validate(req.body);
44
+ if(valid) {
40
45
  return previousMethod.call(this, req, res);
41
46
  } else {
42
47
  res.status(400).json({
43
48
  error: {
44
49
  errorKey: 'client.body.missing',
45
50
  additionalInfo: 'client.extended.badPayload',
46
- detailedInfo: result.errors
51
+ detailedInfo: validate.errors
47
52
  }
48
53
  });
49
54
  }