@opra/core 1.0.0-alpha.9 → 1.0.0-beta.2

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.
Files changed (60) hide show
  1. package/cjs/augmentation/18n.augmentation.js +13 -13
  2. package/cjs/constants.js +1 -2
  3. package/cjs/execution-context.js +1 -0
  4. package/cjs/http/express-adapter.js +22 -20
  5. package/cjs/http/http-adapter.js +2 -5
  6. package/cjs/http/http-context.js +16 -31
  7. package/cjs/http/{impl/http-handler.js → http-handler.js} +194 -169
  8. package/cjs/http/impl/http-outgoing.host.js +2 -2
  9. package/cjs/http/impl/multipart-reader.js +141 -44
  10. package/cjs/http/utils/body-reader.js +0 -1
  11. package/cjs/http/utils/common.js +4 -4
  12. package/cjs/http/utils/concat-readable.js +1 -2
  13. package/cjs/http/utils/convert-to-headers.js +2 -3
  14. package/cjs/http/utils/convert-to-raw-headers.js +1 -2
  15. package/cjs/http/utils/match-known-fields.js +2 -2
  16. package/cjs/http/utils/wrap-exception.js +1 -2
  17. package/cjs/index.js +1 -1
  18. package/cjs/platform-adapter.js +0 -3
  19. package/cjs/type-guards.js +4 -5
  20. package/esm/augmentation/18n.augmentation.js +2 -2
  21. package/esm/constants.js +0 -1
  22. package/esm/execution-context.js +1 -0
  23. package/esm/http/express-adapter.js +22 -20
  24. package/esm/http/http-adapter.js +2 -5
  25. package/esm/http/http-context.js +17 -32
  26. package/esm/http/{impl/http-handler.js → http-handler.js} +195 -170
  27. package/esm/http/impl/http-outgoing.host.js +1 -1
  28. package/esm/http/impl/multipart-reader.js +142 -45
  29. package/esm/http/utils/body-reader.js +0 -1
  30. package/esm/index.js +1 -1
  31. package/esm/package.json +3 -0
  32. package/esm/platform-adapter.js +0 -3
  33. package/package.json +35 -63
  34. package/types/augmentation/http-controller.augmentation.d.ts +1 -2
  35. package/types/constants.d.ts +0 -1
  36. package/types/execution-context.d.ts +2 -1
  37. package/types/helpers/service-base.d.ts +1 -1
  38. package/types/http/express-adapter.d.ts +1 -1
  39. package/types/http/http-adapter.d.ts +35 -8
  40. package/types/http/http-context.d.ts +4 -4
  41. package/types/http/{impl/http-handler.d.ts → http-handler.d.ts} +11 -9
  42. package/types/http/impl/http-incoming.host.d.ts +1 -2
  43. package/types/http/impl/http-outgoing.host.d.ts +1 -1
  44. package/types/http/impl/multipart-reader.d.ts +38 -20
  45. package/types/http/impl/node-incoming-message.host.d.ts +3 -7
  46. package/types/http/impl/node-outgoing-message.host.d.ts +5 -8
  47. package/types/http/interfaces/http-incoming.interface.d.ts +2 -3
  48. package/types/http/interfaces/http-outgoing.interface.d.ts +2 -2
  49. package/types/http/interfaces/node-incoming-message.interface.d.ts +0 -2
  50. package/types/http/interfaces/node-outgoing-message.interface.d.ts +1 -3
  51. package/types/http/utils/body-reader.d.ts +1 -4
  52. package/types/http/utils/concat-readable.d.ts +0 -1
  53. package/types/http/utils/convert-to-raw-headers.d.ts +1 -2
  54. package/types/index.d.cts +28 -0
  55. package/types/index.d.ts +1 -1
  56. package/types/platform-adapter.d.ts +0 -4
  57. package/cjs/helpers/logger.js +0 -35
  58. package/esm/helpers/logger.js +0 -31
  59. package/i18n/i18n/en/error.json +0 -21
  60. package/types/helpers/logger.d.ts +0 -14
@@ -7,10 +7,11 @@ const type_is_1 = tslib_1.__importDefault(require("@browsery/type-is"));
7
7
  const common_1 = require("@opra/common");
8
8
  const content_type_1 = require("content-type");
9
9
  const fast_tokenizer_1 = require("fast-tokenizer");
10
+ const super_fast_md5_1 = require("super-fast-md5");
10
11
  const ts_gems_1 = require("ts-gems");
11
12
  const valgen_1 = require("valgen");
12
- const constants_js_1 = require("../../constants.js");
13
- const wrap_exception_js_1 = require("../utils/wrap-exception.js");
13
+ const constants_js_1 = require("../constants.js");
14
+ const wrap_exception_js_1 = require("./utils/wrap-exception.js");
14
15
  /**
15
16
  * @class HttpHandler
16
17
  */
@@ -42,7 +43,7 @@ class HttpHandler {
42
43
  throw e;
43
44
  if (e instanceof valgen_1.ValidationError) {
44
45
  throw new common_1.BadRequestError({
45
- message: (0, common_1.translate)('error:RESPONSE_VALIDATION,', 'Response validation failed'),
46
+ message: 'Response validation failed',
46
47
  code: 'RESPONSE_VALIDATION',
47
48
  details: e.issues,
48
49
  }, e);
@@ -52,11 +53,14 @@ class HttpHandler {
52
53
  await this.adapter.emitAsync('request', context);
53
54
  // Call interceptors than execute request
54
55
  if (this.adapter.interceptors) {
56
+ const interceptors = this.adapter.interceptors;
55
57
  let i = 0;
56
58
  const next = async () => {
57
- const interceptor = this.adapter.interceptors[i++];
58
- if (interceptor)
59
+ const interceptor = interceptors[i++];
60
+ if (typeof interceptor === 'function')
59
61
  await interceptor(context, next);
62
+ else if (typeof interceptor?.intercept === 'function')
63
+ await interceptor.intercept(context, next);
60
64
  await this._executeRequest(context);
61
65
  };
62
66
  await next();
@@ -68,19 +72,17 @@ class HttpHandler {
68
72
  let e = error;
69
73
  if (e instanceof valgen_1.ValidationError) {
70
74
  e = new common_1.InternalServerError({
71
- message: (0, common_1.translate)('error:RESPONSE_VALIDATION,', 'Response validation failed'),
75
+ message: 'Response validation failed',
72
76
  code: 'RESPONSE_VALIDATION',
73
77
  details: e.issues,
74
78
  }, e);
75
79
  }
76
80
  else
77
81
  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
- });
82
+ if (this.onError)
83
+ await this.onError(context, error);
84
+ context.errors.push(e);
85
+ await this.sendResponse(context);
84
86
  }
85
87
  finally {
86
88
  await context.emitAsync('finish');
@@ -93,7 +95,7 @@ class HttpHandler {
93
95
  async parseRequest(context) {
94
96
  await this._parseParameters(context);
95
97
  await this._parseContentType(context);
96
- if (context.operation.requestBody?.immediateFetch)
98
+ if (context.operation?.requestBody?.immediateFetch)
97
99
  await context.getBody();
98
100
  /** Set default status code as the first status code between 200 and 299 */
99
101
  if (context.operation) {
@@ -113,6 +115,8 @@ class HttpHandler {
113
115
  */
114
116
  async _parseParameters(context) {
115
117
  const { operation, request } = context;
118
+ if (!operation)
119
+ return;
116
120
  let key = '';
117
121
  try {
118
122
  const onFail = (issue) => {
@@ -214,6 +218,7 @@ class HttpHandler {
214
218
  }
215
219
  }
216
220
  for (const prm of paramsLeft) {
221
+ key = String(prm.name);
217
222
  // Throw error for required parameters
218
223
  if (prm.required) {
219
224
  const decode = getDecoder(prm);
@@ -239,6 +244,8 @@ class HttpHandler {
239
244
  */
240
245
  async _parseContentType(context) {
241
246
  const { request, operation } = context;
247
+ if (!operation)
248
+ return;
242
249
  if (operation.requestBody?.content.length) {
243
250
  let mediaType;
244
251
  let contentType = request.header('content-type');
@@ -265,7 +272,7 @@ class HttpHandler {
265
272
  const responseValue = await context.operationHandler.call(context.controllerInstance, context);
266
273
  const { response } = context;
267
274
  if (!response.writableEnded) {
268
- await this._sendResponse(context, responseValue).finally(() => {
275
+ await this.sendResponse(context, responseValue).finally(() => {
269
276
  if (!response.writableEnded)
270
277
  response.end();
271
278
  });
@@ -277,94 +284,182 @@ class HttpHandler {
277
284
  * @param responseValue
278
285
  * @protected
279
286
  */
280
- async _sendResponse(context, responseValue) {
287
+ async sendResponse(context, responseValue) {
288
+ if (context.errors.length)
289
+ return this._sendErrorResponse(context);
281
290
  const { response } = context;
282
291
  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);
292
+ try {
293
+ const responseArgs = this._determineResponseArgs(context, responseValue);
294
+ const { operationResponse, statusCode } = responseArgs;
295
+ let { contentType, body } = responseArgs;
296
+ const operationResultType = document.node.getDataType(common_1.OperationResult);
297
+ let operationResultEncoder = this[constants_js_1.kAssetCache].get(operationResultType, 'encode');
298
+ if (!operationResultEncoder) {
299
+ operationResultEncoder = operationResultType.generateCodec('encode', {
300
+ ignoreWriteonlyFields: true,
301
+ ignoreHiddenFields: true,
302
+ });
303
+ this[constants_js_1.kAssetCache].set(operationResultType, 'encode', operationResultEncoder);
304
+ }
305
+ /** Validate response */
306
+ if (operationResponse?.type) {
307
+ if (!(body == null && statusCode === common_1.HttpStatusCode.NO_CONTENT)) {
308
+ /** Generate encoder */
309
+ const projection = responseArgs.projection || '*';
310
+ const assetKey = (0, super_fast_md5_1.md5)(String(projection));
311
+ let encode = this[constants_js_1.kAssetCache].get(operationResponse, 'encode:' + assetKey);
312
+ if (!encode) {
313
+ encode = operationResponse.type.generateCodec('encode', {
314
+ partial: operationResponse.partial,
315
+ projection,
316
+ ignoreWriteonlyFields: true,
317
+ ignoreHiddenFields: true,
318
+ onFail: issue => `Response body validation failed: ` + issue.message,
319
+ });
320
+ if (operationResponse) {
321
+ if (operationResponse.isArray)
322
+ encode = valgen_1.vg.isArray(encode);
323
+ this[constants_js_1.kAssetCache].set(operationResponse, 'encode:' + assetKey, encode);
324
+ }
325
+ }
326
+ /** Encode body */
327
+ if (operationResponse.type.extendsFrom(operationResultType)) {
328
+ if (body instanceof common_1.OperationResult)
329
+ body = encode(body);
330
+ else {
331
+ body.payload = encode(body.payload);
332
+ body = operationResultEncoder(body);
333
+ }
307
334
  }
308
- }
309
- /** Encode body */
310
- if (operationResponse.type.extendsFrom(operationResultType)) {
311
- if (body instanceof common_1.OperationResult)
312
- body = encode(body);
313
335
  else {
314
- body.payload = encode(body.payload);
315
- body = operationResultEncoder(body);
336
+ if (body instanceof common_1.OperationResult &&
337
+ contentType &&
338
+ type_is_1.default.is(contentType, [common_1.MimeTypes.opra_response_json])) {
339
+ body.payload = encode(body.payload);
340
+ body = operationResultEncoder(body);
341
+ }
342
+ else {
343
+ body = encode(body);
344
+ }
316
345
  }
317
- }
318
- else {
319
346
  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);
347
+ operationResponse.type &&
348
+ operationResponse.type !== document.node.getDataType(common_1.OperationResult)) {
349
+ body.type = operationResponse.type.name ? operationResponse.type.name : '#embedded';
324
350
  }
325
- else
326
- body = encode(body);
327
- }
328
- if (body instanceof common_1.OperationResult && operationResponse.type) {
329
- body.type = operationResponse.type.name ? operationResponse.type.name : '#embedded';
330
351
  }
331
352
  }
332
- }
333
- else if (body != null) {
334
- if (body instanceof common_1.OperationResult) {
335
- body = operationResultEncoder(body);
336
- contentType = common_1.MimeTypes.opra_response_json;
337
- }
338
- else if (Buffer.isBuffer(body))
339
- contentType = common_1.MimeTypes.binary;
340
- else if (typeof body === 'object') {
341
- contentType = contentType || common_1.MimeTypes.json;
342
- if (typeof body.toJSON === 'function')
343
- body = body.toJSON();
353
+ else if (body != null) {
354
+ if (body instanceof common_1.OperationResult) {
355
+ body = operationResultEncoder(body);
356
+ contentType = common_1.MimeTypes.opra_response_json;
357
+ }
358
+ else if (Buffer.isBuffer(body))
359
+ contentType = common_1.MimeTypes.binary;
360
+ else if (typeof body === 'object') {
361
+ contentType = contentType || common_1.MimeTypes.json;
362
+ if (typeof body.toJSON === 'function')
363
+ body = body.toJSON();
364
+ }
365
+ else {
366
+ contentType = contentType || common_1.MimeTypes.text;
367
+ body = String(body);
368
+ }
344
369
  }
345
- else {
346
- contentType = contentType || common_1.MimeTypes.text;
347
- body = String(body);
370
+ /** Set content-type header value if not set */
371
+ if (contentType && contentType !== responseArgs.contentType)
372
+ response.setHeader('content-type', contentType);
373
+ response.status(statusCode);
374
+ if (body == null) {
375
+ response.end();
376
+ return;
348
377
  }
378
+ let x;
379
+ if (Buffer.isBuffer(body) || (0, common_1.isReadableStream)(body))
380
+ x = body;
381
+ else if ((0, common_1.isBlob)(body))
382
+ x = body.stream();
383
+ else if (typeof body === 'object')
384
+ x = JSON.stringify(body);
385
+ else
386
+ x = String(body);
387
+ response.end(x);
388
+ }
389
+ catch (error) {
390
+ context.errors.push(error);
391
+ return this._sendErrorResponse(context);
349
392
  }
350
- /** Set content-type header value if not set */
351
- if (contentType && contentType !== responseArgs.contentType)
352
- response.setHeader('content-type', contentType);
353
- response.status(statusCode);
354
- if (body == null) {
393
+ }
394
+ async _sendErrorResponse(context) {
395
+ context.errors = this._wrapExceptions(context.errors);
396
+ try {
397
+ await this.adapter.emitAsync('error', context);
398
+ context.errors = this._wrapExceptions(context.errors);
399
+ }
400
+ catch (e) {
401
+ context.errors = this._wrapExceptions([e, ...context.errors]);
402
+ }
403
+ const { response, errors } = context;
404
+ if (response.headersSent) {
355
405
  response.end();
356
406
  return;
357
407
  }
358
- let x;
359
- if (Buffer.isBuffer(body) || (0, common_1.isReadableStream)(body))
360
- x = body;
361
- else if ((0, common_1.isBlob)(body))
362
- x = body.stream();
363
- else if (typeof body === 'object')
364
- x = JSON.stringify(body);
365
- else
366
- x = String(body);
367
- response.end(x);
408
+ let status = response.statusCode || 0;
409
+ if (!status || status < Number(common_1.HttpStatusCode.BAD_REQUEST)) {
410
+ status = errors[0].status;
411
+ if (status < Number(common_1.HttpStatusCode.BAD_REQUEST))
412
+ status = common_1.HttpStatusCode.INTERNAL_SERVER_ERROR;
413
+ }
414
+ response.statusCode = status;
415
+ const { document } = this.adapter;
416
+ const dt = document.node.getComplexType('OperationResult');
417
+ let encode = this[constants_js_1.kAssetCache].get(dt, 'encode');
418
+ if (!encode) {
419
+ encode = dt.generateCodec('encode', { ignoreWriteonlyFields: true });
420
+ this[constants_js_1.kAssetCache].set(dt, 'encode', encode);
421
+ }
422
+ // const { i18n } = this.adapter;
423
+ const bodyObject = new common_1.OperationResult({
424
+ errors: errors.map(x => {
425
+ const o = x.toJSON();
426
+ if (!(process.env.NODE_ENV === 'dev' || process.env.NODE_ENV === 'development'))
427
+ delete o.stack;
428
+ return o; // i18n.deep(o);
429
+ }),
430
+ });
431
+ const body = encode(bodyObject);
432
+ response.setHeader(common_1.HttpHeaderCodes.Content_Type, common_1.MimeTypes.opra_response_json + '; charset=utf-8');
433
+ response.setHeader(common_1.HttpHeaderCodes.Cache_Control, 'no-cache');
434
+ response.setHeader(common_1.HttpHeaderCodes.Pragma, 'no-cache');
435
+ response.setHeader(common_1.HttpHeaderCodes.Expires, '-1');
436
+ response.setHeader(common_1.HttpHeaderCodes.X_Opra_Version, common_1.OpraSchema.SpecVersion);
437
+ response.send((0, common_1.safeJsonStringify)(body));
438
+ response.end();
439
+ }
440
+ async sendDocumentSchema(context) {
441
+ const { request, response } = context;
442
+ const { document } = this.adapter;
443
+ response.setHeader('content-type', common_1.MimeTypes.json);
444
+ const url = new URL(request.originalUrl || request.url || '/', 'http://tempuri.org');
445
+ const { searchParams } = url;
446
+ const documentId = searchParams.get('id');
447
+ const doc = documentId ? document.findDocument(documentId) : document;
448
+ if (!doc) {
449
+ context.errors.push(new common_1.BadRequestError({
450
+ message: `Document with given id [${documentId}] does not exists`,
451
+ }));
452
+ return this.sendResponse(context);
453
+ }
454
+ /** Check if response cache exists */
455
+ let responseBody = this[constants_js_1.kAssetCache].get(doc, `$schema`);
456
+ /** Create response if response cache does not exists */
457
+ if (!responseBody) {
458
+ const schema = doc.export();
459
+ responseBody = JSON.stringify(schema);
460
+ this[constants_js_1.kAssetCache].set(doc, `$schema`, responseBody);
461
+ }
462
+ response.end(responseBody);
368
463
  }
369
464
  /**
370
465
  *
@@ -391,7 +486,7 @@ class HttpHandler {
391
486
  let responseArgs = this[constants_js_1.kAssetCache].get(response, cacheKey);
392
487
  if (!responseArgs) {
393
488
  responseArgs = { statusCode, contentType };
394
- if (operation.responses.length) {
489
+ if (operation?.responses.length) {
395
490
  /** Filter available HttpOperationResponse instances according to status code. */
396
491
  const filteredResponses = operation.responses.filter(r => r.statusCode.find(sc => sc.start <= statusCode && sc.end >= statusCode));
397
492
  /** Throw InternalServerError if controller returns non-configured status code */
@@ -423,6 +518,8 @@ class HttpHandler {
423
518
  : operationResponse.contentType);
424
519
  if (typeof ct === 'string')
425
520
  responseArgs.contentType = contentType = ct;
521
+ else if (operationResponse.type)
522
+ responseArgs.contentType = common_1.MimeTypes.opra_response_json;
426
523
  }
427
524
  }
428
525
  }
@@ -434,6 +531,10 @@ class HttpHandler {
434
531
  }
435
532
  if (!hasBody)
436
533
  delete responseArgs.contentType;
534
+ if (operation?.composition?.startsWith('Entity.')) {
535
+ if (context.queryParams.projection)
536
+ responseArgs.projection = context.queryParams.projection;
537
+ }
437
538
  this[constants_js_1.kAssetCache].set(response, cacheKey, { ...responseArgs });
438
539
  }
439
540
  /** Fix response value according to composition */
@@ -491,56 +592,10 @@ class HttpHandler {
491
592
  responseArgs.body = body;
492
593
  return responseArgs;
493
594
  }
494
- async sendDocumentSchema(context) {
495
- const { request, response } = context;
496
- const { document } = this.adapter;
497
- response.setHeader('content-type', common_1.MimeTypes.json);
498
- const url = new URL(request.originalUrl || request.url || '/', 'http://tempuri.org');
499
- const { searchParams } = url;
500
- const documentId = searchParams.get('id');
501
- const doc = documentId ? document.findDocument(documentId) : document;
502
- if (!doc) {
503
- return this.sendErrorResponse(response, [
504
- new common_1.BadRequestError({
505
- message: `Document with given id [${documentId}] does not exists`,
506
- }),
507
- ]);
508
- }
509
- /** Check if response cache exists */
510
- let responseBody = this[constants_js_1.kAssetCache].get(doc, `$schema`);
511
- /** Create response if response cache does not exists */
512
- if (!responseBody) {
513
- const schema = doc.export();
514
- responseBody = JSON.stringify(schema);
515
- this[constants_js_1.kAssetCache].set(doc, `$schema`, responseBody);
516
- }
517
- response.end(responseBody);
518
- }
519
- async sendErrorResponse(response, errors) {
520
- if (response.headersSent) {
521
- response.end();
522
- return;
523
- }
524
- if (!errors.length)
525
- errors.push((0, wrap_exception_js_1.wrapException)({ status: response.statusCode || 500 }));
526
- const { logger } = this.adapter;
527
- errors.forEach(x => {
528
- if (x instanceof common_1.OpraException) {
529
- switch (x.severity) {
530
- case 'fatal':
531
- logger.fatal(x);
532
- break;
533
- case 'warning':
534
- logger.warn(x);
535
- break;
536
- default:
537
- logger.error(x);
538
- }
539
- }
540
- else
541
- logger.fatal(x);
542
- });
543
- const wrappedErrors = errors.map(wrap_exception_js_1.wrapException);
595
+ _wrapExceptions(exceptions) {
596
+ const wrappedErrors = exceptions.map(wrap_exception_js_1.wrapException);
597
+ if (!wrappedErrors.length)
598
+ wrappedErrors.push(new common_1.InternalServerError());
544
599
  // Sort errors from fatal to info
545
600
  wrappedErrors.sort((a, b) => {
546
601
  const i = common_1.IssueSeverity.Keys.indexOf(a.severity) - common_1.IssueSeverity.Keys.indexOf(b.severity);
@@ -548,37 +603,7 @@ class HttpHandler {
548
603
  return b.status - a.status;
549
604
  return i;
550
605
  });
551
- let status = response.statusCode || 0;
552
- if (!status || status < Number(common_1.HttpStatusCode.BAD_REQUEST)) {
553
- status = wrappedErrors[0].status;
554
- if (status < Number(common_1.HttpStatusCode.BAD_REQUEST))
555
- status = common_1.HttpStatusCode.INTERNAL_SERVER_ERROR;
556
- }
557
- response.statusCode = status;
558
- const { document } = this.adapter;
559
- const dt = document.node.getComplexType('OperationResult');
560
- let encode = this[constants_js_1.kAssetCache].get(dt, 'encode');
561
- if (!encode) {
562
- encode = dt.generateCodec('encode', { ignoreWriteonlyFields: true });
563
- this[constants_js_1.kAssetCache].set(dt, 'encode', encode);
564
- }
565
- const { i18n } = this.adapter;
566
- const bodyObject = new common_1.OperationResult({
567
- errors: wrappedErrors.map(x => {
568
- const o = x.toJSON();
569
- if (!(process.env.NODE_ENV === 'dev' || process.env.NODE_ENV === 'development'))
570
- delete o.stack;
571
- return i18n.deep(o);
572
- }),
573
- });
574
- const body = encode(bodyObject);
575
- response.setHeader(common_1.HttpHeaderCodes.Content_Type, common_1.MimeTypes.opra_response_json + '; charset=utf-8');
576
- response.setHeader(common_1.HttpHeaderCodes.Cache_Control, 'no-cache');
577
- response.setHeader(common_1.HttpHeaderCodes.Pragma, 'no-cache');
578
- response.setHeader(common_1.HttpHeaderCodes.Expires, '-1');
579
- response.setHeader(common_1.HttpHeaderCodes.X_Opra_Version, common_1.OpraSchema.SpecVersion);
580
- response.send(JSON.stringify(body));
581
- response.end();
606
+ return wrappedErrors;
582
607
  }
583
608
  }
584
609
  exports.HttpHandler = HttpHandler;
@@ -6,6 +6,7 @@
6
6
  Object.defineProperty(exports, "__esModule", { value: true });
7
7
  exports.HttpOutgoingHost = void 0;
8
8
  const tslib_1 = require("tslib");
9
+ const node_path_1 = tslib_1.__importDefault(require("node:path"));
9
10
  const common_1 = require("@opra/common");
10
11
  const content_disposition_1 = tslib_1.__importDefault(require("content-disposition"));
11
12
  const content_type_1 = tslib_1.__importDefault(require("content-type"));
@@ -13,14 +14,13 @@ const cookie_1 = tslib_1.__importDefault(require("cookie"));
13
14
  const cookie_signature_1 = tslib_1.__importDefault(require("cookie-signature"));
14
15
  const encodeurl_1 = tslib_1.__importDefault(require("encodeurl"));
15
16
  const mime_types_1 = tslib_1.__importDefault(require("mime-types"));
16
- const path_1 = tslib_1.__importDefault(require("path"));
17
17
  const putil_varhelpers_1 = require("putil-varhelpers");
18
18
  const vary_1 = tslib_1.__importDefault(require("vary"));
19
19
  const charsetRegExp = /;\s*charset\s*=/;
20
20
  class HttpOutgoingHost {
21
21
  attachment(filename) {
22
22
  if (filename)
23
- this.contentType(path_1.default.extname(filename));
23
+ this.contentType(node_path_1.default.extname(filename));
24
24
  this.setHeader('Content-Disposition', (0, content_disposition_1.default)(filename));
25
25
  return this;
26
26
  }