@opra/core 1.0.0-alpha.23 → 1.0.0-alpha.25

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/cjs/constants.js CHANGED
@@ -1,5 +1,4 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.kAssetCache = exports.kHandler = void 0;
4
- exports.kHandler = Symbol.for('kHandler');
3
+ exports.kAssetCache = void 0;
5
4
  exports.kAssetCache = Symbol.for('kAssetCache');
@@ -8,6 +8,7 @@ const strict_typed_events_1 = require("strict-typed-events");
8
8
  class ExecutionContext extends strict_typed_events_1.AsyncEventEmitter {
9
9
  constructor(init) {
10
10
  super();
11
+ this.errors = [];
11
12
  this.document = init.document;
12
13
  this.protocol = init.protocol;
13
14
  this.platform = init.platform;
@@ -5,11 +5,11 @@ const tslib_1 = require("tslib");
5
5
  const common_1 = require("@opra/common");
6
6
  const express_1 = require("express");
7
7
  const nodePath = tslib_1.__importStar(require("path"));
8
- const constants_js_1 = require("../constants.js");
9
8
  const http_adapter_js_1 = require("./http-adapter.js");
10
9
  const http_context_js_1 = require("./http-context.js");
11
10
  const http_incoming_interface_js_1 = require("./interfaces/http-incoming.interface.js");
12
11
  const http_outgoing_interface_js_1 = require("./interfaces/http-outgoing.interface.js");
12
+ const wrap_exception_1 = require("./utils/wrap-exception");
13
13
  class ExpressAdapter extends http_adapter_js_1.HttpAdapter {
14
14
  constructor(app, document, options) {
15
15
  super(document, options);
@@ -40,7 +40,8 @@ class ExpressAdapter extends http_adapter_js_1.HttpAdapter {
40
40
  await resource.onShutdown.call(instance, resource);
41
41
  }
42
42
  catch (e) {
43
- this.logger.error(e);
43
+ if (this.listenerCount('error'))
44
+ this.emit('error', (0, wrap_exception_1.wrapException)(e));
44
45
  }
45
46
  }
46
47
  }
@@ -80,7 +81,7 @@ class ExpressAdapter extends http_adapter_js_1.HttpAdapter {
80
81
  /** Add an endpoint that returns document schema */
81
82
  router.get('/\\$schema', (_req, _res, next) => {
82
83
  const context = createContext(_req, _res);
83
- this[constants_js_1.kHandler].sendDocumentSchema(context).catch(next);
84
+ this.handler.sendDocumentSchema(context).catch(next);
84
85
  });
85
86
  /** Add operation endpoints */
86
87
  if (this.api.controllers.size) {
@@ -100,13 +101,13 @@ class ExpressAdapter extends http_adapter_js_1.HttpAdapter {
100
101
  operation,
101
102
  operationHandler,
102
103
  });
103
- this[constants_js_1.kHandler]
104
+ this.handler
104
105
  .handleRequest(context)
105
106
  .then(() => {
106
107
  if (!_res.headersSent)
107
108
  _next();
108
109
  })
109
- .catch((e) => this.logger.fatal(e));
110
+ .catch((e) => this.emit('error', e));
110
111
  });
111
112
  }
112
113
  if (controller.controllers.size) {
@@ -119,19 +120,15 @@ class ExpressAdapter extends http_adapter_js_1.HttpAdapter {
119
120
  }
120
121
  /** Add an endpoint that returns 404 error at last */
121
122
  router.use('*', (_req, _res, next) => {
122
- const res = http_outgoing_interface_js_1.HttpOutgoing.from(_res);
123
- // const url = new URL(_req.originalUrl, '')
124
- this[constants_js_1.kHandler]
125
- .sendErrorResponse(res, [
126
- new common_1.NotFoundError({
127
- message: `No endpoint found for [${_req.method}]${_req.baseUrl}`,
128
- details: {
129
- path: _req.baseUrl,
130
- method: _req.method,
131
- },
132
- }),
133
- ])
134
- .catch(next);
123
+ const context = createContext(_req, _res);
124
+ context.errors.push(new common_1.NotFoundError({
125
+ message: `No endpoint found at [${_req.method}]${_req.baseUrl}`,
126
+ details: {
127
+ path: _req.baseUrl,
128
+ method: _req.method,
129
+ },
130
+ }));
131
+ this.handler.sendResponse(context).catch(next);
135
132
  });
136
133
  }
137
134
  _createControllers(controller) {
@@ -2,9 +2,8 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.HttpAdapter = void 0;
4
4
  const common_1 = require("@opra/common");
5
- const constants_js_1 = require("../constants.js");
6
5
  const platform_adapter_js_1 = require("../platform-adapter.js");
7
- const http_handler_js_1 = require("./impl/http-handler.js");
6
+ const http_handler_js_1 = require("./http-handler.js");
8
7
  /**
9
8
  *
10
9
  * @class HttpAdapter
@@ -15,10 +14,8 @@ class HttpAdapter extends platform_adapter_js_1.PlatformAdapter {
15
14
  this.protocol = 'http';
16
15
  if (!(document.api instanceof common_1.HttpApi))
17
16
  throw new TypeError(`The document does not expose an HTTP Api`);
18
- this[constants_js_1.kHandler] = new http_handler_js_1.HttpHandler(this);
17
+ this.handler = new http_handler_js_1.HttpHandler(this);
19
18
  this.interceptors = [...(options?.interceptors || [])];
20
- if (options?.onRequest)
21
- this.on('request', options.onRequest);
22
19
  }
23
20
  get api() {
24
21
  return this.document.api;
@@ -29,6 +29,10 @@ class HttpContext extends execution_context_js_1.ExecutionContext {
29
29
  this.pathParams = init.pathParams || {};
30
30
  this.queryParams = init.queryParams || {};
31
31
  this._body = init.body;
32
+ this.on('finish', () => {
33
+ if (this._multipartReader)
34
+ this._multipartReader.purge().catch(() => undefined);
35
+ });
32
36
  }
33
37
  get isMultipart() {
34
38
  return !!this.request.is('multipart');
@@ -38,21 +42,21 @@ class HttpContext extends execution_context_js_1.ExecutionContext {
38
42
  throw new common_1.InternalServerError('Request content is not a multipart content');
39
43
  if (this._multipartReader)
40
44
  return this._multipartReader;
41
- const { request, mediaType } = this;
45
+ const { mediaType } = this;
42
46
  if (mediaType?.contentType) {
43
47
  const arr = Array.isArray(mediaType.contentType) ? mediaType.contentType : [mediaType.contentType];
44
48
  const contentType = arr.find(ct => type_is_1.default.is(ct, ['multipart']));
45
49
  if (!contentType)
46
50
  throw new common_1.NotAcceptableError('This endpoint does not accept multipart requests');
47
51
  }
48
- const reader = new multipart_reader_js_1.MultipartReader(request, {
49
- maxFields: mediaType?.maxFields,
50
- maxFieldsSize: mediaType?.maxFieldsSize,
51
- maxFiles: mediaType?.maxFiles,
52
- maxFileSize: mediaType?.maxFileSize,
53
- maxTotalFileSize: mediaType?.maxTotalFileSize,
54
- minFileSize: mediaType?.minFileSize,
55
- });
52
+ const reader = new multipart_reader_js_1.MultipartReader(this, {
53
+ limits: {
54
+ fields: mediaType?.maxFields,
55
+ fieldSize: mediaType?.maxFieldsSize,
56
+ files: mediaType?.maxFiles,
57
+ fileSize: mediaType?.maxFileSize,
58
+ },
59
+ }, mediaType);
56
60
  this._multipartReader = reader;
57
61
  return reader;
58
62
  }
@@ -70,7 +74,7 @@ class HttpContext extends execution_context_js_1.ExecutionContext {
70
74
  if (mediaType && multipartFields?.length) {
71
75
  const fieldsFound = new Map();
72
76
  for (const item of parts) {
73
- const field = mediaType.findMultipartField(item.fieldName, item.type);
77
+ const field = mediaType.findMultipartField(item.field, item.kind);
74
78
  if (field) {
75
79
  fieldsFound.set(field, true);
76
80
  this._body.push(item);
@@ -9,15 +9,15 @@ const content_type_1 = require("content-type");
9
9
  const fast_tokenizer_1 = require("fast-tokenizer");
10
10
  const ts_gems_1 = require("ts-gems");
11
11
  const valgen_1 = require("valgen");
12
- const constants_js_1 = require("../../constants.js");
13
- const wrap_exception_js_1 = require("../utils/wrap-exception.js");
12
+ const constants_1 = require("../constants");
13
+ const wrap_exception_1 = require("./utils/wrap-exception");
14
14
  /**
15
15
  * @class HttpHandler
16
16
  */
17
17
  class HttpHandler {
18
18
  constructor(adapter) {
19
19
  this.adapter = adapter;
20
- this[constants_js_1.kAssetCache] = adapter[constants_js_1.kAssetCache];
20
+ this[constants_1.kAssetCache] = adapter[constants_1.kAssetCache];
21
21
  }
22
22
  /**
23
23
  * Main http request handler
@@ -42,7 +42,7 @@ class HttpHandler {
42
42
  throw e;
43
43
  if (e instanceof valgen_1.ValidationError) {
44
44
  throw new common_1.BadRequestError({
45
- message: (0, common_1.translate)('error:RESPONSE_VALIDATION,', 'Response validation failed'),
45
+ message: 'Response validation failed',
46
46
  code: 'RESPONSE_VALIDATION',
47
47
  details: e.issues,
48
48
  }, e);
@@ -68,19 +68,17 @@ class HttpHandler {
68
68
  let e = error;
69
69
  if (e instanceof valgen_1.ValidationError) {
70
70
  e = new common_1.InternalServerError({
71
- message: (0, common_1.translate)('error:RESPONSE_VALIDATION,', 'Response validation failed'),
71
+ message: 'Response validation failed',
72
72
  code: 'RESPONSE_VALIDATION',
73
73
  details: e.issues,
74
74
  }, e);
75
75
  }
76
76
  else
77
- e = (0, wrap_exception_js_1.wrapException)(e);
78
- response.status(e.statusCode || e.status || common_1.HttpStatusCode.INTERNAL_SERVER_ERROR);
79
- response.contentType(common_1.MimeTypes.opra_response_json);
80
- await this._sendResponse(context, new common_1.OperationResult({ errors: [e.toJSON()] })).finally(() => {
81
- if (!response.finished)
82
- response.end();
83
- });
77
+ e = (0, wrap_exception_1.wrapException)(e);
78
+ if (this.onError)
79
+ await this.onError(context, error);
80
+ context.errors.push(e);
81
+ await this.sendResponse(context);
84
82
  }
85
83
  finally {
86
84
  await context.emitAsync('finish');
@@ -121,10 +119,10 @@ class HttpHandler {
121
119
  };
122
120
  /** prepare decoders */
123
121
  const getDecoder = (prm) => {
124
- let decode = this[constants_js_1.kAssetCache].get(prm, 'decode');
122
+ let decode = this[constants_1.kAssetCache].get(prm, 'decode');
125
123
  if (!decode) {
126
124
  decode = prm.type?.generateCodec('decode', { ignoreReadonlyFields: true }) || valgen_1.vg.isAny();
127
- this[constants_js_1.kAssetCache].set(prm, 'decode', decode);
125
+ this[constants_1.kAssetCache].set(prm, 'decode', decode);
128
126
  }
129
127
  return decode;
130
128
  };
@@ -214,6 +212,7 @@ class HttpHandler {
214
212
  }
215
213
  }
216
214
  for (const prm of paramsLeft) {
215
+ key = String(prm.name);
217
216
  // Throw error for required parameters
218
217
  if (prm.required) {
219
218
  const decode = getDecoder(prm);
@@ -265,7 +264,7 @@ class HttpHandler {
265
264
  const responseValue = await context.operationHandler.call(context.controllerInstance, context);
266
265
  const { response } = context;
267
266
  if (!response.writableEnded) {
268
- await this._sendResponse(context, responseValue).finally(() => {
267
+ await this.sendResponse(context, responseValue).finally(() => {
269
268
  if (!response.writableEnded)
270
269
  response.end();
271
270
  });
@@ -277,96 +276,156 @@ class HttpHandler {
277
276
  * @param responseValue
278
277
  * @protected
279
278
  */
280
- async _sendResponse(context, responseValue) {
279
+ async sendResponse(context, responseValue) {
280
+ if (context.errors.length)
281
+ return this._sendErrorResponse(context);
281
282
  const { response } = context;
282
283
  const { document } = this.adapter;
283
- const responseArgs = this._determineResponseArgs(context, responseValue);
284
- const { operationResponse, statusCode } = responseArgs;
285
- let { contentType, body } = responseArgs;
286
- const operationResultType = document.node.getDataType(common_1.OperationResult);
287
- let operationResultEncoder = this[constants_js_1.kAssetCache].get(operationResultType, 'encode');
288
- if (!operationResultEncoder) {
289
- operationResultEncoder = operationResultType.generateCodec('encode', { ignoreWriteonlyFields: true });
290
- this[constants_js_1.kAssetCache].set(operationResultType, 'encode', operationResultEncoder);
291
- }
292
- /** Validate response */
293
- if (operationResponse?.type) {
294
- if (!(body == null && statusCode === common_1.HttpStatusCode.NO_CONTENT)) {
295
- /** Generate encoder */
296
- let encode = this[constants_js_1.kAssetCache].get(operationResponse, 'encode');
297
- if (!encode) {
298
- encode = operationResponse.type.generateCodec('encode', {
299
- partial: operationResponse.partial,
300
- projection: '*',
301
- ignoreWriteonlyFields: true,
302
- });
303
- if (operationResponse) {
304
- if (operationResponse.isArray)
305
- encode = valgen_1.vg.isArray(encode);
306
- this[constants_js_1.kAssetCache].set(operationResponse, 'encode', encode);
284
+ try {
285
+ const responseArgs = this._determineResponseArgs(context, responseValue);
286
+ const { operationResponse, statusCode } = responseArgs;
287
+ let { contentType, body } = responseArgs;
288
+ const operationResultType = document.node.getDataType(common_1.OperationResult);
289
+ let operationResultEncoder = this[constants_1.kAssetCache].get(operationResultType, 'encode');
290
+ if (!operationResultEncoder) {
291
+ operationResultEncoder = operationResultType.generateCodec('encode', { ignoreWriteonlyFields: true });
292
+ this[constants_1.kAssetCache].set(operationResultType, 'encode', operationResultEncoder);
293
+ }
294
+ /** Validate response */
295
+ if (operationResponse?.type) {
296
+ if (!(body == null && statusCode === common_1.HttpStatusCode.NO_CONTENT)) {
297
+ /** Generate encoder */
298
+ let encode = this[constants_1.kAssetCache].get(operationResponse, 'encode');
299
+ if (!encode) {
300
+ encode = operationResponse.type.generateCodec('encode', {
301
+ partial: operationResponse.partial,
302
+ projection: '*',
303
+ ignoreWriteonlyFields: true,
304
+ onFail: issue => `Response body validation failed: ` + issue.message,
305
+ });
306
+ if (operationResponse) {
307
+ if (operationResponse.isArray)
308
+ encode = valgen_1.vg.isArray(encode);
309
+ this[constants_1.kAssetCache].set(operationResponse, 'encode', encode);
310
+ }
311
+ }
312
+ /** Encode body */
313
+ if (operationResponse.type.extendsFrom(operationResultType)) {
314
+ if (body instanceof common_1.OperationResult)
315
+ body = encode(body);
316
+ else {
317
+ body.payload = encode(body.payload);
318
+ body = operationResultEncoder(body);
319
+ }
307
320
  }
308
- }
309
- /** Encode body */
310
- if (operationResponse.type.extendsFrom(operationResultType)) {
311
- if (body instanceof common_1.OperationResult)
312
- body = encode(body);
313
321
  else {
314
- body.payload = encode(body.payload);
315
- body = operationResultEncoder(body);
322
+ if (body instanceof common_1.OperationResult &&
323
+ contentType &&
324
+ type_is_1.default.is(contentType, [common_1.MimeTypes.opra_response_json])) {
325
+ body.payload = encode(body.payload);
326
+ body = operationResultEncoder(body);
327
+ }
328
+ else {
329
+ body = encode(body);
330
+ }
316
331
  }
317
- }
318
- else {
319
332
  if (body instanceof common_1.OperationResult &&
320
- contentType &&
321
- type_is_1.default.is(contentType, [common_1.MimeTypes.opra_response_json])) {
322
- body.payload = encode(body.payload);
323
- body = operationResultEncoder(body);
333
+ operationResponse.type &&
334
+ operationResponse.type !== document.node.getDataType(common_1.OperationResult)) {
335
+ body.type = operationResponse.type.name ? operationResponse.type.name : '#embedded';
324
336
  }
325
- else
326
- body = encode(body);
327
- }
328
- if (body instanceof common_1.OperationResult &&
329
- operationResponse.type &&
330
- operationResponse.type !== document.node.getDataType(common_1.OperationResult)) {
331
- body.type = operationResponse.type.name ? operationResponse.type.name : '#embedded';
332
337
  }
333
338
  }
334
- }
335
- else if (body != null) {
336
- if (body instanceof common_1.OperationResult) {
337
- body = operationResultEncoder(body);
338
- contentType = common_1.MimeTypes.opra_response_json;
339
- }
340
- else if (Buffer.isBuffer(body))
341
- contentType = common_1.MimeTypes.binary;
342
- else if (typeof body === 'object') {
343
- contentType = contentType || common_1.MimeTypes.json;
344
- if (typeof body.toJSON === 'function')
345
- body = body.toJSON();
339
+ else if (body != null) {
340
+ if (body instanceof common_1.OperationResult) {
341
+ body = operationResultEncoder(body);
342
+ contentType = common_1.MimeTypes.opra_response_json;
343
+ }
344
+ else if (Buffer.isBuffer(body))
345
+ contentType = common_1.MimeTypes.binary;
346
+ else if (typeof body === 'object') {
347
+ contentType = contentType || common_1.MimeTypes.json;
348
+ if (typeof body.toJSON === 'function')
349
+ body = body.toJSON();
350
+ }
351
+ else {
352
+ contentType = contentType || common_1.MimeTypes.text;
353
+ body = String(body);
354
+ }
346
355
  }
347
- else {
348
- contentType = contentType || common_1.MimeTypes.text;
349
- body = String(body);
356
+ /** Set content-type header value if not set */
357
+ if (contentType && contentType !== responseArgs.contentType)
358
+ response.setHeader('content-type', contentType);
359
+ response.status(statusCode);
360
+ if (body == null) {
361
+ response.end();
362
+ return;
350
363
  }
364
+ let x;
365
+ if (Buffer.isBuffer(body) || (0, common_1.isReadableStream)(body))
366
+ x = body;
367
+ else if ((0, common_1.isBlob)(body))
368
+ x = body.stream();
369
+ else if (typeof body === 'object')
370
+ x = JSON.stringify(body);
371
+ else
372
+ x = String(body);
373
+ response.end(x);
374
+ }
375
+ catch (error) {
376
+ context.errors.push(error);
377
+ return this._sendErrorResponse(context);
351
378
  }
352
- /** Set content-type header value if not set */
353
- if (contentType && contentType !== responseArgs.contentType)
354
- response.setHeader('content-type', contentType);
355
- response.status(statusCode);
356
- if (body == null) {
379
+ }
380
+ async _sendErrorResponse(context) {
381
+ const { response, errors } = context;
382
+ if (response.headersSent) {
357
383
  response.end();
358
384
  return;
359
385
  }
360
- let x;
361
- if (Buffer.isBuffer(body) || (0, common_1.isReadableStream)(body))
362
- x = body;
363
- else if ((0, common_1.isBlob)(body))
364
- x = body.stream();
365
- else if (typeof body === 'object')
366
- x = JSON.stringify(body);
367
- else
368
- x = String(body);
369
- response.end(x);
386
+ const wrappedErrors = errors.map(wrap_exception_1.wrapException);
387
+ if (!wrappedErrors.length)
388
+ wrappedErrors.push(new common_1.InternalServerError());
389
+ // Sort errors from fatal to info
390
+ wrappedErrors.sort((a, b) => {
391
+ const i = common_1.IssueSeverity.Keys.indexOf(a.severity) - common_1.IssueSeverity.Keys.indexOf(b.severity);
392
+ if (i === 0)
393
+ return b.status - a.status;
394
+ return i;
395
+ });
396
+ context.errors = wrappedErrors;
397
+ let status = response.statusCode || 0;
398
+ if (!status || status < Number(common_1.HttpStatusCode.BAD_REQUEST)) {
399
+ status = wrappedErrors[0].status;
400
+ if (status < Number(common_1.HttpStatusCode.BAD_REQUEST))
401
+ status = common_1.HttpStatusCode.INTERNAL_SERVER_ERROR;
402
+ }
403
+ response.statusCode = status;
404
+ this.adapter.emitAsync('error', wrappedErrors[0], context).catch(() => undefined);
405
+ const { document } = this.adapter;
406
+ const dt = document.node.getComplexType('OperationResult');
407
+ let encode = this[constants_1.kAssetCache].get(dt, 'encode');
408
+ if (!encode) {
409
+ encode = dt.generateCodec('encode', { ignoreWriteonlyFields: true });
410
+ this[constants_1.kAssetCache].set(dt, 'encode', encode);
411
+ }
412
+ const { i18n } = this.adapter;
413
+ const bodyObject = new common_1.OperationResult({
414
+ errors: wrappedErrors.map(x => {
415
+ const o = x.toJSON();
416
+ if (!(process.env.NODE_ENV === 'dev' || process.env.NODE_ENV === 'development'))
417
+ delete o.stack;
418
+ return i18n.deep(o);
419
+ }),
420
+ });
421
+ const body = encode(bodyObject);
422
+ response.setHeader(common_1.HttpHeaderCodes.Content_Type, common_1.MimeTypes.opra_response_json + '; charset=utf-8');
423
+ response.setHeader(common_1.HttpHeaderCodes.Cache_Control, 'no-cache');
424
+ response.setHeader(common_1.HttpHeaderCodes.Pragma, 'no-cache');
425
+ response.setHeader(common_1.HttpHeaderCodes.Expires, '-1');
426
+ response.setHeader(common_1.HttpHeaderCodes.X_Opra_Version, common_1.OpraSchema.SpecVersion);
427
+ response.send(JSON.stringify(body));
428
+ response.end();
370
429
  }
371
430
  /**
372
431
  *
@@ -390,7 +449,7 @@ class HttpHandler {
390
449
  }
391
450
  let operationResponse;
392
451
  const cacheKey = `HttpOperationResponse:${statusCode}${contentType ? ':' + contentType : ''}`;
393
- let responseArgs = this[constants_js_1.kAssetCache].get(response, cacheKey);
452
+ let responseArgs = this[constants_1.kAssetCache].get(response, cacheKey);
394
453
  if (!responseArgs) {
395
454
  responseArgs = { statusCode, contentType };
396
455
  if (operation.responses.length) {
@@ -425,6 +484,8 @@ class HttpHandler {
425
484
  : operationResponse.contentType);
426
485
  if (typeof ct === 'string')
427
486
  responseArgs.contentType = contentType = ct;
487
+ else if (operationResponse.type)
488
+ responseArgs.contentType = common_1.MimeTypes.opra_response_json;
428
489
  }
429
490
  }
430
491
  }
@@ -436,7 +497,7 @@ class HttpHandler {
436
497
  }
437
498
  if (!hasBody)
438
499
  delete responseArgs.contentType;
439
- this[constants_js_1.kAssetCache].set(response, cacheKey, { ...responseArgs });
500
+ this[constants_1.kAssetCache].set(response, cacheKey, { ...responseArgs });
440
501
  }
441
502
  /** Fix response value according to composition */
442
503
  const composition = operationResponse?.owner.composition;
@@ -502,85 +563,20 @@ class HttpHandler {
502
563
  const documentId = searchParams.get('id');
503
564
  const doc = documentId ? document.findDocument(documentId) : document;
504
565
  if (!doc) {
505
- return this.sendErrorResponse(response, [
506
- new common_1.BadRequestError({
507
- message: `Document with given id [${documentId}] does not exists`,
508
- }),
509
- ]);
566
+ context.errors.push(new common_1.BadRequestError({
567
+ message: `Document with given id [${documentId}] does not exists`,
568
+ }));
569
+ return this.sendResponse(context);
510
570
  }
511
571
  /** Check if response cache exists */
512
- let responseBody = this[constants_js_1.kAssetCache].get(doc, `$schema`);
572
+ let responseBody = this[constants_1.kAssetCache].get(doc, `$schema`);
513
573
  /** Create response if response cache does not exists */
514
574
  if (!responseBody) {
515
575
  const schema = doc.export();
516
576
  responseBody = JSON.stringify(schema);
517
- this[constants_js_1.kAssetCache].set(doc, `$schema`, responseBody);
577
+ this[constants_1.kAssetCache].set(doc, `$schema`, responseBody);
518
578
  }
519
579
  response.end(responseBody);
520
580
  }
521
- async sendErrorResponse(response, errors) {
522
- if (response.headersSent) {
523
- response.end();
524
- return;
525
- }
526
- if (!errors.length)
527
- errors.push((0, wrap_exception_js_1.wrapException)({ status: response.statusCode || 500 }));
528
- const { logger } = this.adapter;
529
- errors.forEach(x => {
530
- if (x instanceof common_1.OpraException) {
531
- switch (x.severity) {
532
- case 'fatal':
533
- logger.fatal(x);
534
- break;
535
- case 'warning':
536
- logger.warn(x);
537
- break;
538
- default:
539
- logger.error(x);
540
- }
541
- }
542
- else
543
- logger.fatal(x);
544
- });
545
- const wrappedErrors = errors.map(wrap_exception_js_1.wrapException);
546
- // Sort errors from fatal to info
547
- wrappedErrors.sort((a, b) => {
548
- const i = common_1.IssueSeverity.Keys.indexOf(a.severity) - common_1.IssueSeverity.Keys.indexOf(b.severity);
549
- if (i === 0)
550
- return b.status - a.status;
551
- return i;
552
- });
553
- let status = response.statusCode || 0;
554
- if (!status || status < Number(common_1.HttpStatusCode.BAD_REQUEST)) {
555
- status = wrappedErrors[0].status;
556
- if (status < Number(common_1.HttpStatusCode.BAD_REQUEST))
557
- status = common_1.HttpStatusCode.INTERNAL_SERVER_ERROR;
558
- }
559
- response.statusCode = status;
560
- const { document } = this.adapter;
561
- const dt = document.node.getComplexType('OperationResult');
562
- let encode = this[constants_js_1.kAssetCache].get(dt, 'encode');
563
- if (!encode) {
564
- encode = dt.generateCodec('encode', { ignoreWriteonlyFields: true });
565
- this[constants_js_1.kAssetCache].set(dt, 'encode', encode);
566
- }
567
- const { i18n } = this.adapter;
568
- const bodyObject = new common_1.OperationResult({
569
- errors: wrappedErrors.map(x => {
570
- const o = x.toJSON();
571
- if (!(process.env.NODE_ENV === 'dev' || process.env.NODE_ENV === 'development'))
572
- delete o.stack;
573
- return i18n.deep(o);
574
- }),
575
- });
576
- const body = encode(bodyObject);
577
- response.setHeader(common_1.HttpHeaderCodes.Content_Type, common_1.MimeTypes.opra_response_json + '; charset=utf-8');
578
- response.setHeader(common_1.HttpHeaderCodes.Cache_Control, 'no-cache');
579
- response.setHeader(common_1.HttpHeaderCodes.Pragma, 'no-cache');
580
- response.setHeader(common_1.HttpHeaderCodes.Expires, '-1');
581
- response.setHeader(common_1.HttpHeaderCodes.X_Opra_Version, common_1.OpraSchema.SpecVersion);
582
- response.send(JSON.stringify(body));
583
- response.end();
584
- }
585
581
  }
586
582
  exports.HttpHandler = HttpHandler;