@opra/core 0.23.0 → 0.23.1

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.
@@ -100,7 +100,7 @@ class HttpAdapterBase extends platform_adapter_host_js_1.PlatformAdapterHost {
100
100
  const wrappedErrors = errors.map(common_1.wrapException);
101
101
  // Sort errors from fatal to info
102
102
  wrappedErrors.sort((a, b) => {
103
- const i = common_1.IssueSeverity.Keys.indexOf(a.issue.severity) - common_1.IssueSeverity.Keys.indexOf(b.issue.severity);
103
+ const i = common_1.IssueSeverity.Keys.indexOf(a.severity) - common_1.IssueSeverity.Keys.indexOf(b.severity);
104
104
  if (i === 0)
105
105
  return b.status - a.status;
106
106
  return i;
@@ -112,9 +112,9 @@ class HttpAdapterBase extends platform_adapter_host_js_1.PlatformAdapterHost {
112
112
  status = common_1.HttpStatusCodes.INTERNAL_SERVER_ERROR;
113
113
  }
114
114
  outgoing.statusCode = status;
115
- const body = this._i18n.deep({
116
- errors: wrappedErrors.map(x => x.issue)
117
- });
115
+ const body = {
116
+ errors: wrappedErrors.map(x => this._i18n.deep(x.toJSON()))
117
+ };
118
118
  outgoing.setHeader(common_1.HttpHeaderCodes.Content_Type, 'application/json; charset=utf-8');
119
119
  outgoing.setHeader(common_1.HttpHeaderCodes.Cache_Control, 'no-cache');
120
120
  outgoing.setHeader(common_1.HttpHeaderCodes.Pragma, 'no-cache');
@@ -4,6 +4,7 @@ exports.EntityRequestHandler = void 0;
4
4
  const tslib_1 = require("tslib");
5
5
  const body_parser_1 = tslib_1.__importDefault(require("body-parser"));
6
6
  const putil_varhelpers_1 = require("putil-varhelpers");
7
+ const valgen = tslib_1.__importStar(require("valgen"));
7
8
  const common_1 = require("@opra/common");
8
9
  const operation_context_js_1 = require("../../operation-context.js");
9
10
  const request_host_js_1 = require("../../request.host.js");
@@ -33,7 +34,21 @@ class EntityRequestHandler extends request_handler_base_js_1.RequestHandlerBase
33
34
  context.errors.push(...response.errors);
34
35
  return;
35
36
  }
36
- await this.sendResponse(context);
37
+ try {
38
+ await this.sendResponse(context);
39
+ }
40
+ catch (e) {
41
+ if (e instanceof common_1.OpraException)
42
+ throw e;
43
+ if (e instanceof valgen.ValidationError) {
44
+ throw new common_1.InternalServerError({
45
+ message: (0, common_1.translate)('error:RESPONSE_VALIDATION,', 'Response validation failed'),
46
+ code: 'RESPONSE_VALIDATION',
47
+ details: e.issues
48
+ }, e);
49
+ }
50
+ throw new common_1.InternalServerError(e);
51
+ }
37
52
  }
38
53
  async parseRequest(incoming) {
39
54
  const p = incoming.parsedUrl.path[0];
@@ -47,6 +62,13 @@ class EntityRequestHandler extends request_handler_base_js_1.RequestHandlerBase
47
62
  catch (e) {
48
63
  if (e instanceof common_1.OpraException)
49
64
  throw e;
65
+ if (e instanceof valgen.ValidationError) {
66
+ throw new common_1.BadRequestError({
67
+ message: (0, common_1.translate)('error:REQUEST_VALIDATION,', 'Request validation failed'),
68
+ code: 'REQUEST_VALIDATION',
69
+ details: e.issues
70
+ }, e);
71
+ }
50
72
  throw new common_1.BadRequestError(e);
51
73
  }
52
74
  }
@@ -136,7 +158,8 @@ class EntityRequestHandler extends request_handler_base_js_1.RequestHandlerBase
136
158
  const operationMeta = await this.assertOperation(resource, 'create');
137
159
  const jsonReader = this.getBodyLoader(operationMeta);
138
160
  const decode = resource.getDecoder('create');
139
- const data = decode(await jsonReader(incoming), { coerce: true });
161
+ let data = await jsonReader(incoming);
162
+ data = decode(data, { coerce: true });
140
163
  const pick = (0, query_parsers_js_1.parseArrayParam)(params.get('$pick'));
141
164
  const omit = (0, query_parsers_js_1.parseArrayParam)(params.get('$omit'));
142
165
  const include = (0, query_parsers_js_1.parseArrayParam)(params.get('$include'));
@@ -228,7 +251,8 @@ class EntityRequestHandler extends request_handler_base_js_1.RequestHandlerBase
228
251
  const operationMeta = await this.assertOperation(resource, 'update');
229
252
  const jsonReader = this.getBodyLoader(operationMeta);
230
253
  const decode = resource.getDecoder('update');
231
- const data = decode(await jsonReader(incoming), { coerce: true });
254
+ let data = await jsonReader(incoming);
255
+ data = decode(data, { coerce: true });
232
256
  const pick = (0, query_parsers_js_1.parseArrayParam)(params.get('$pick'));
233
257
  const omit = (0, query_parsers_js_1.parseArrayParam)(params.get('$omit'));
234
258
  const include = (0, query_parsers_js_1.parseArrayParam)(params.get('$include'));
@@ -250,7 +274,8 @@ class EntityRequestHandler extends request_handler_base_js_1.RequestHandlerBase
250
274
  const operationMeta = await this.assertOperation(resource, 'updateMany');
251
275
  const jsonReader = this.getBodyLoader(operationMeta);
252
276
  const decode = resource.getDecoder('updateMany');
253
- const data = decode(await jsonReader(incoming), { coerce: true });
277
+ let data = await jsonReader(incoming);
278
+ data = decode(data, { coerce: true });
254
279
  const filter = resource.normalizeFilter(params.get('$filter'));
255
280
  return new request_host_js_1.RequestHost({
256
281
  controller: operationMeta.controller,
@@ -280,7 +305,8 @@ class EntityRequestHandler extends request_handler_base_js_1.RequestHandlerBase
280
305
  const operationMeta = await this.assertOperation(resource, 'create');
281
306
  const jsonReader = this.getBodyLoader(operationMeta);
282
307
  const decode = resource.getDecoder('create');
283
- const data = decode(await jsonReader(incoming), { coerce: true });
308
+ let data = await jsonReader(incoming);
309
+ data = decode(data, { coerce: true });
284
310
  const pick = (0, query_parsers_js_1.parseArrayParam)(params.get('$pick'));
285
311
  const omit = (0, query_parsers_js_1.parseArrayParam)(params.get('$omit'));
286
312
  const include = (0, query_parsers_js_1.parseArrayParam)(params.get('$include'));
@@ -330,7 +356,8 @@ class EntityRequestHandler extends request_handler_base_js_1.RequestHandlerBase
330
356
  const operationMeta = await this.assertOperation(resource, 'update');
331
357
  const jsonReader = this.getBodyLoader(operationMeta);
332
358
  const decode = resource.getDecoder('update');
333
- const data = decode(await jsonReader(incoming), { coerce: true });
359
+ let data = await jsonReader(incoming);
360
+ data = decode(data, { coerce: true });
334
361
  const pick = (0, query_parsers_js_1.parseArrayParam)(params.get('$pick'));
335
362
  const omit = (0, query_parsers_js_1.parseArrayParam)(params.get('$omit'));
336
363
  const include = (0, query_parsers_js_1.parseArrayParam)(params.get('$include'));
@@ -97,7 +97,7 @@ export class HttpAdapterBase extends PlatformAdapterHost {
97
97
  const wrappedErrors = errors.map(wrapException);
98
98
  // Sort errors from fatal to info
99
99
  wrappedErrors.sort((a, b) => {
100
- const i = IssueSeverity.Keys.indexOf(a.issue.severity) - IssueSeverity.Keys.indexOf(b.issue.severity);
100
+ const i = IssueSeverity.Keys.indexOf(a.severity) - IssueSeverity.Keys.indexOf(b.severity);
101
101
  if (i === 0)
102
102
  return b.status - a.status;
103
103
  return i;
@@ -109,9 +109,9 @@ export class HttpAdapterBase extends PlatformAdapterHost {
109
109
  status = HttpStatusCodes.INTERNAL_SERVER_ERROR;
110
110
  }
111
111
  outgoing.statusCode = status;
112
- const body = this._i18n.deep({
113
- errors: wrappedErrors.map(x => x.issue)
114
- });
112
+ const body = {
113
+ errors: wrappedErrors.map(x => this._i18n.deep(x.toJSON()))
114
+ };
115
115
  outgoing.setHeader(HttpHeaderCodes.Content_Type, 'application/json; charset=utf-8');
116
116
  outgoing.setHeader(HttpHeaderCodes.Cache_Control, 'no-cache');
117
117
  outgoing.setHeader(HttpHeaderCodes.Pragma, 'no-cache');
@@ -1,6 +1,7 @@
1
1
  import bodyParser from 'body-parser';
2
2
  import { toBoolean, toInt } from 'putil-varhelpers';
3
- import { BadRequestError, Collection, HttpHeaderCodes, HttpStatusCodes, InternalServerError, MethodNotAllowedError, OpraException, ResourceNotFoundError, Singleton, } from '@opra/common';
3
+ import * as valgen from 'valgen';
4
+ import { BadRequestError, Collection, HttpHeaderCodes, HttpStatusCodes, InternalServerError, MethodNotAllowedError, OpraException, ResourceNotFoundError, Singleton, translate, } from '@opra/common';
4
5
  import { OperationContext } from '../../operation-context.js';
5
6
  import { RequestHost } from '../../request.host.js';
6
7
  import { ResponseHost } from '../../response.host.js';
@@ -29,7 +30,21 @@ export class EntityRequestHandler extends RequestHandlerBase {
29
30
  context.errors.push(...response.errors);
30
31
  return;
31
32
  }
32
- await this.sendResponse(context);
33
+ try {
34
+ await this.sendResponse(context);
35
+ }
36
+ catch (e) {
37
+ if (e instanceof OpraException)
38
+ throw e;
39
+ if (e instanceof valgen.ValidationError) {
40
+ throw new InternalServerError({
41
+ message: translate('error:RESPONSE_VALIDATION,', 'Response validation failed'),
42
+ code: 'RESPONSE_VALIDATION',
43
+ details: e.issues
44
+ }, e);
45
+ }
46
+ throw new InternalServerError(e);
47
+ }
33
48
  }
34
49
  async parseRequest(incoming) {
35
50
  const p = incoming.parsedUrl.path[0];
@@ -43,6 +58,13 @@ export class EntityRequestHandler extends RequestHandlerBase {
43
58
  catch (e) {
44
59
  if (e instanceof OpraException)
45
60
  throw e;
61
+ if (e instanceof valgen.ValidationError) {
62
+ throw new BadRequestError({
63
+ message: translate('error:REQUEST_VALIDATION,', 'Request validation failed'),
64
+ code: 'REQUEST_VALIDATION',
65
+ details: e.issues
66
+ }, e);
67
+ }
46
68
  throw new BadRequestError(e);
47
69
  }
48
70
  }
@@ -132,7 +154,8 @@ export class EntityRequestHandler extends RequestHandlerBase {
132
154
  const operationMeta = await this.assertOperation(resource, 'create');
133
155
  const jsonReader = this.getBodyLoader(operationMeta);
134
156
  const decode = resource.getDecoder('create');
135
- const data = decode(await jsonReader(incoming), { coerce: true });
157
+ let data = await jsonReader(incoming);
158
+ data = decode(data, { coerce: true });
136
159
  const pick = parseArrayParam(params.get('$pick'));
137
160
  const omit = parseArrayParam(params.get('$omit'));
138
161
  const include = parseArrayParam(params.get('$include'));
@@ -224,7 +247,8 @@ export class EntityRequestHandler extends RequestHandlerBase {
224
247
  const operationMeta = await this.assertOperation(resource, 'update');
225
248
  const jsonReader = this.getBodyLoader(operationMeta);
226
249
  const decode = resource.getDecoder('update');
227
- const data = decode(await jsonReader(incoming), { coerce: true });
250
+ let data = await jsonReader(incoming);
251
+ data = decode(data, { coerce: true });
228
252
  const pick = parseArrayParam(params.get('$pick'));
229
253
  const omit = parseArrayParam(params.get('$omit'));
230
254
  const include = parseArrayParam(params.get('$include'));
@@ -246,7 +270,8 @@ export class EntityRequestHandler extends RequestHandlerBase {
246
270
  const operationMeta = await this.assertOperation(resource, 'updateMany');
247
271
  const jsonReader = this.getBodyLoader(operationMeta);
248
272
  const decode = resource.getDecoder('updateMany');
249
- const data = decode(await jsonReader(incoming), { coerce: true });
273
+ let data = await jsonReader(incoming);
274
+ data = decode(data, { coerce: true });
250
275
  const filter = resource.normalizeFilter(params.get('$filter'));
251
276
  return new RequestHost({
252
277
  controller: operationMeta.controller,
@@ -276,7 +301,8 @@ export class EntityRequestHandler extends RequestHandlerBase {
276
301
  const operationMeta = await this.assertOperation(resource, 'create');
277
302
  const jsonReader = this.getBodyLoader(operationMeta);
278
303
  const decode = resource.getDecoder('create');
279
- const data = decode(await jsonReader(incoming), { coerce: true });
304
+ let data = await jsonReader(incoming);
305
+ data = decode(data, { coerce: true });
280
306
  const pick = parseArrayParam(params.get('$pick'));
281
307
  const omit = parseArrayParam(params.get('$omit'));
282
308
  const include = parseArrayParam(params.get('$include'));
@@ -326,7 +352,8 @@ export class EntityRequestHandler extends RequestHandlerBase {
326
352
  const operationMeta = await this.assertOperation(resource, 'update');
327
353
  const jsonReader = this.getBodyLoader(operationMeta);
328
354
  const decode = resource.getDecoder('update');
329
- const data = decode(await jsonReader(incoming), { coerce: true });
355
+ let data = await jsonReader(incoming);
356
+ data = decode(data, { coerce: true });
330
357
  const pick = parseArrayParam(params.get('$pick'));
331
358
  const omit = parseArrayParam(params.get('$omit'));
332
359
  const include = parseArrayParam(params.get('$include'));
@@ -8,6 +8,8 @@
8
8
  "NOT_FOUND": "Not found",
9
9
  "UNAUTHORIZED": "You have not been authenticated to perform this action",
10
10
  "UNPROCESSABLE_ENTITY": "Unprocessable entity",
11
+ "REQUEST_VALIDATION": "Request validation failed",
12
+ "RESPONSE_VALIDATION": "Response validation failed",
11
13
  "RESOURCE_NOT_FOUND": "Resource not found: '{{resource}}'",
12
14
  "RESOURCE_CONFLICT": "There is already an other {{resource}} resource with same field values ({{fields}})",
13
15
  "RESOLVER_FORBIDDEN": "The {{resource}} endpoint does not accept '{{operation}}' operations",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@opra/core",
3
- "version": "0.23.0",
3
+ "version": "0.23.1",
4
4
  "description": "Opra schema package",
5
5
  "author": "Panates",
6
6
  "license": "MIT",
@@ -27,7 +27,7 @@
27
27
  "clean:cover": "rimraf ../../coverage/core"
28
28
  },
29
29
  "dependencies": {
30
- "@opra/common": "^0.23.0",
30
+ "@opra/common": "^0.23.1",
31
31
  "accepts": "^1.3.8",
32
32
  "content-disposition": "^0.5.4",
33
33
  "content-type": "^1.0.5",
@@ -37,11 +37,11 @@
37
37
  "formidable": "^3.5.0",
38
38
  "fresh": "^0.5.2",
39
39
  "mime-types": "^2.1.35",
40
- "power-tasks": "^1.7.0",
41
- "putil-varhelpers": "^1.6.5",
40
+ "power-tasks": "^1.7.1",
42
41
  "putil-isplainobject": "^1.1.5",
42
+ "putil-varhelpers": "^1.6.5",
43
43
  "range-parser": "^1.2.1",
44
- "strict-typed-events": "^2.3.1",
44
+ "strict-typed-events": "^2.3.2",
45
45
  "type-is": "^1.6.18",
46
46
  "vary": "^1.1.2"
47
47
  },
@@ -57,7 +57,7 @@
57
57
  "@types/cookie-signature": "^1.1.0",
58
58
  "@types/encodeurl": "^1.0.0",
59
59
  "@types/express": "^4.17.17",
60
- "@types/formidable": "^3.4.0",
60
+ "@types/formidable": "^3.4.1",
61
61
  "@types/fresh": "^0.5.0",
62
62
  "@types/mime-types": "^2.1.1",
63
63
  "@types/range-parser": "^1.2.4",
@@ -65,7 +65,7 @@
65
65
  "@types/vary": "^1.1.0",
66
66
  "crypto-browserify": "^3.12.0",
67
67
  "path-browserify": "^1.0.1",
68
- "ts-gems": "^2.4.0"
68
+ "ts-gems": "^2.4.1"
69
69
  },
70
70
  "type": "module",
71
71
  "types": "types/index.d.ts",