@opra/core 0.0.8 → 0.0.11

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 (84) hide show
  1. package/cjs/exception/api-exception.js +32 -35
  2. package/cjs/exception/{errors → http-errors}/bad-request.error.js +7 -4
  3. package/cjs/exception/{errors → http-errors}/failed-dependency.error.js +7 -4
  4. package/cjs/exception/{errors → http-errors}/forbidden.error.js +7 -4
  5. package/cjs/exception/{errors → http-errors}/internal-server.error.js +10 -5
  6. package/cjs/exception/{errors → http-errors}/method-not-allowed.error.js +7 -4
  7. package/cjs/exception/{errors → http-errors}/not-found.error.js +6 -3
  8. package/cjs/exception/{errors → http-errors}/unauthorized.error.js +6 -3
  9. package/cjs/exception/{errors → http-errors}/unprocessable-entity.error.js +7 -4
  10. package/cjs/exception/index.js +9 -7
  11. package/cjs/exception/resource-errors/resource-conflict.error.js +19 -0
  12. package/cjs/exception/wrap-error.js +2 -2
  13. package/cjs/implementation/adapter/adapter.js +31 -29
  14. package/cjs/implementation/adapter/express-adapter.js +40 -9
  15. package/cjs/implementation/adapter/http-adapter.js +28 -35
  16. package/cjs/implementation/{execution-context.js → query-context.js} +18 -22
  17. package/cjs/implementation/resource/entity-resource-handler.js +16 -12
  18. package/cjs/implementation/resource/resource-handler.js +1 -1
  19. package/cjs/implementation/schema-generator.js +38 -51
  20. package/cjs/index.js +3 -4
  21. package/cjs/interfaces/{http-context.interface.js → execution-context.interface.js} +0 -0
  22. package/cjs/interfaces/{execution-query.interface.js → query.interface.js} +24 -24
  23. package/cjs/utils/create-i18n.js +21 -0
  24. package/cjs/utils/get-caller-file.util.js +19 -0
  25. package/cjs/utils/internal-data-types.js +54 -17
  26. package/esm/exception/api-exception.d.ts +3 -2
  27. package/esm/exception/api-exception.js +32 -35
  28. package/esm/exception/{errors → http-errors}/bad-request.error.d.ts +2 -1
  29. package/esm/exception/{errors → http-errors}/bad-request.error.js +7 -4
  30. package/esm/exception/{errors → http-errors}/failed-dependency.error.d.ts +2 -1
  31. package/esm/exception/{errors → http-errors}/failed-dependency.error.js +7 -4
  32. package/esm/exception/{errors → http-errors}/forbidden.error.d.ts +2 -1
  33. package/esm/exception/{errors → http-errors}/forbidden.error.js +7 -4
  34. package/esm/exception/{errors → http-errors}/internal-server.error.d.ts +2 -1
  35. package/esm/exception/{errors → http-errors}/internal-server.error.js +9 -5
  36. package/esm/exception/{errors → http-errors}/method-not-allowed.error.d.ts +2 -1
  37. package/esm/exception/{errors → http-errors}/method-not-allowed.error.js +7 -4
  38. package/esm/exception/{errors → http-errors}/not-found.error.d.ts +2 -1
  39. package/esm/exception/{errors → http-errors}/not-found.error.js +6 -3
  40. package/esm/exception/{errors → http-errors}/unauthorized.error.d.ts +2 -1
  41. package/esm/exception/{errors → http-errors}/unauthorized.error.js +6 -3
  42. package/esm/exception/{errors → http-errors}/unprocessable-entity.error.d.ts +2 -1
  43. package/esm/exception/{errors → http-errors}/unprocessable-entity.error.js +7 -4
  44. package/esm/exception/index.d.ts +9 -7
  45. package/esm/exception/index.js +9 -7
  46. package/esm/exception/resource-errors/resource-conflict.error.d.ts +4 -0
  47. package/esm/exception/resource-errors/resource-conflict.error.js +15 -0
  48. package/esm/exception/wrap-error.js +2 -2
  49. package/esm/implementation/adapter/adapter.d.ts +22 -14
  50. package/esm/implementation/adapter/adapter.js +31 -29
  51. package/esm/implementation/adapter/express-adapter.d.ts +2 -2
  52. package/esm/implementation/adapter/express-adapter.js +40 -9
  53. package/esm/implementation/adapter/http-adapter.d.ts +11 -12
  54. package/esm/implementation/adapter/http-adapter.js +28 -35
  55. package/esm/implementation/query-context.d.ts +32 -0
  56. package/esm/implementation/{execution-context.js → query-context.js} +15 -18
  57. package/esm/implementation/resource/container-resource-handler.d.ts +2 -2
  58. package/esm/implementation/resource/entity-resource-handler.d.ts +3 -3
  59. package/esm/implementation/resource/entity-resource-handler.js +16 -12
  60. package/esm/implementation/resource/resource-handler.d.ts +3 -3
  61. package/esm/implementation/resource/resource-handler.js +1 -1
  62. package/esm/implementation/schema-generator.js +38 -51
  63. package/esm/index.d.ts +3 -4
  64. package/esm/index.js +3 -4
  65. package/esm/interfaces/execution-context.interface.d.ts +39 -0
  66. package/esm/interfaces/{http-context.interface.js → execution-context.interface.js} +0 -0
  67. package/esm/interfaces/query.interface.d.ts +108 -0
  68. package/esm/interfaces/{execution-query.interface.js → query.interface.js} +23 -23
  69. package/esm/services/entity-resource-controller.d.ts +11 -11
  70. package/esm/types.d.ts +1 -3
  71. package/esm/utils/create-i18n.d.ts +3 -0
  72. package/esm/utils/create-i18n.js +16 -0
  73. package/esm/utils/get-caller-file.util.d.ts +1 -0
  74. package/esm/utils/get-caller-file.util.js +15 -0
  75. package/esm/utils/internal-data-types.d.ts +2 -1
  76. package/esm/utils/internal-data-types.js +53 -16
  77. package/i18n/en/error.json +12 -0
  78. package/package.json +10 -6
  79. package/cjs/interfaces/user-context.interface.js +0 -2
  80. package/esm/implementation/execution-context.d.ts +0 -42
  81. package/esm/interfaces/execution-query.interface.d.ts +0 -102
  82. package/esm/interfaces/http-context.interface.d.ts +0 -23
  83. package/esm/interfaces/user-context.interface.d.ts +0 -3
  84. package/esm/interfaces/user-context.interface.js +0 -1
@@ -13,12 +13,26 @@ class ApiException extends Error {
13
13
  constructor(response, cause) {
14
14
  super('');
15
15
  this._initName();
16
+ this.status = index_js_1.HttpStatus.INTERNAL_SERVER_ERROR;
17
+ cause = cause || (response instanceof Error ? response : undefined);
16
18
  if (cause)
17
19
  Object.defineProperty(this, 'cause', { enumerable: false, configurable: true, writable: true, value: cause });
18
- else if (response instanceof Error)
19
- Object.defineProperty(this, 'cause', { enumerable: false, configurable: true, writable: true, value: response });
20
- this.status = index_js_1.HttpStatus.INTERNAL_SERVER_ERROR;
21
- this._initResponse(response);
20
+ if (response instanceof Error)
21
+ this._initErrorInstance(response);
22
+ else if (typeof response === 'string')
23
+ this._initResponse({ message: response });
24
+ else
25
+ this._initResponse(response);
26
+ if (!this.response.severity)
27
+ if (this.status >= 500)
28
+ this.response.severity = 'fatal';
29
+ else
30
+ this.response.severity = 'error';
31
+ if (this.cause instanceof Error && this.cause.stack) {
32
+ if (ApiException.stackAsDiagnostics)
33
+ this.response.diagnostics = this.cause.stack.split('\n');
34
+ this.stack = this.cause.stack;
35
+ }
22
36
  }
23
37
  setStatus(status) {
24
38
  this.status = status;
@@ -27,37 +41,20 @@ class ApiException extends Error {
27
41
  _initName() {
28
42
  this.name = this.constructor.name;
29
43
  }
30
- _initResponse(init) {
31
- if (init && typeof init === 'object') {
32
- const x = init;
33
- if (typeof x.status === 'number')
34
- this.setStatus(x.status);
35
- else if (typeof x.getStatus === 'function')
36
- this.setStatus(x.getStatus());
37
- }
38
- if (typeof init === 'object') {
39
- const x = init;
40
- this.response = {
41
- message: x.message || x.details || ('' + init),
42
- };
43
- if (!(init instanceof Error))
44
- Object.assign(this.response, init);
45
- }
46
- else {
47
- this.response = {
48
- message: '' + init,
49
- };
50
- }
51
- if (this.cause instanceof Error && this.cause.stack) {
52
- if (ApiException.stackAsDiagnostics)
53
- this.response.diagnostics = this.cause.stack.split('\n');
54
- this.stack = this.cause.stack;
55
- }
56
- if (!this.response.severity)
57
- if (this.status >= 500)
58
- this.response.severity = 'fatal';
59
- else
60
- this.response.severity = 'error';
44
+ _initErrorInstance(init) {
45
+ this._initResponse({
46
+ message: init.message
47
+ });
48
+ if (typeof init.status === 'number')
49
+ this.setStatus(init.status);
50
+ else if (typeof init.getStatus === 'function')
51
+ this.setStatus(init.getStatus());
52
+ }
53
+ _initResponse(response) {
54
+ this.response = {
55
+ message: 'Unknown error',
56
+ ...response
57
+ };
61
58
  }
62
59
  static wrap(response) {
63
60
  if (response instanceof ApiException)
@@ -11,13 +11,16 @@ const api_exception_js_1 = require("../api-exception.js");
11
11
  */
12
12
  class BadRequestError extends api_exception_js_1.ApiException {
13
13
  constructor(response, cause) {
14
- super({
15
- message: (0, i18n_1.translate)('error:BAD_REQUEST', 'Bad request'),
14
+ super(response, cause);
15
+ this.status = index_js_1.HttpStatus.BAD_REQUEST;
16
+ }
17
+ _initResponse(response) {
18
+ super._initResponse({
19
+ message: (0, i18n_1.translate)('error:BAD_REQUEST'),
16
20
  severity: 'error',
17
21
  code: 'BAD_REQUEST',
18
22
  ...response
19
- }, cause);
20
- this.status = index_js_1.HttpStatus.BAD_REQUEST;
23
+ });
21
24
  }
22
25
  }
23
26
  exports.BadRequestError = BadRequestError;
@@ -10,13 +10,16 @@ const api_exception_js_1 = require("../api-exception.js");
10
10
  */
11
11
  class FailedDependencyError extends api_exception_js_1.ApiException {
12
12
  constructor(response, cause) {
13
- super({
14
- message: (0, i18n_1.translate)('error:FAILED_DEPENDENCY', 'The request failed due to failure of a previous request.'),
13
+ super(response, cause);
14
+ this.status = index_js_1.HttpStatus.FAILED_DEPENDENCY;
15
+ }
16
+ _initResponse(response) {
17
+ super._initResponse({
18
+ message: (0, i18n_1.translate)('error:FAILED_DEPENDENCY'),
15
19
  severity: 'error',
16
20
  code: 'FAILED_DEPENDENCY',
17
21
  ...response
18
- }, cause);
19
- this.status = index_js_1.HttpStatus.FAILED_DEPENDENCY;
22
+ });
20
23
  }
21
24
  }
22
25
  exports.FailedDependencyError = FailedDependencyError;
@@ -12,13 +12,16 @@ const api_exception_js_1 = require("../api-exception.js");
12
12
  */
13
13
  class ForbiddenError extends api_exception_js_1.ApiException {
14
14
  constructor(response, cause) {
15
- super({
16
- message: (0, i18n_1.translate)('error:FORBIDDEN', 'Forbidden'),
15
+ super(response, cause);
16
+ this.status = index_js_1.HttpStatus.FORBIDDEN;
17
+ }
18
+ _initResponse(response) {
19
+ super._initResponse({
20
+ message: (0, i18n_1.translate)('error:FORBIDDEN'),
17
21
  severity: 'error',
18
22
  code: 'FORBIDDEN',
19
23
  ...response
20
- }, cause);
21
- this.status = index_js_1.HttpStatus.FORBIDDEN;
24
+ });
22
25
  }
23
26
  }
24
27
  exports.ForbiddenError = ForbiddenError;
@@ -1,6 +1,8 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.InternalServerError = void 0;
4
+ const tslib_1 = require("tslib");
5
+ const lodash_1 = tslib_1.__importDefault(require("lodash"));
4
6
  const i18n_1 = require("@opra/i18n");
5
7
  const index_js_1 = require("../../enums/index.js");
6
8
  const api_exception_js_1 = require("../api-exception.js");
@@ -10,13 +12,16 @@ const api_exception_js_1 = require("../api-exception.js");
10
12
  */
11
13
  class InternalServerError extends api_exception_js_1.ApiException {
12
14
  constructor(response, cause) {
13
- super({
14
- message: (0, i18n_1.translate)('error:INTERNAL_SERVER_ERROR', 'Internal server error'),
15
+ super(response, cause);
16
+ this.status = index_js_1.HttpStatus.INTERNAL_SERVER_ERROR;
17
+ }
18
+ _initResponse(response) {
19
+ super._initResponse({
20
+ message: (0, i18n_1.translate)('error:INTERNAL_SERVER_ERROR'),
15
21
  severity: 'error',
16
22
  code: 'INTERNAL_SERVER_ERROR',
17
- ...response
18
- }, cause);
19
- this.status = index_js_1.HttpStatus.INTERNAL_SERVER_ERROR;
23
+ ...lodash_1.default.omitBy(response, lodash_1.default.isNil)
24
+ });
20
25
  }
21
26
  }
22
27
  exports.InternalServerError = InternalServerError;
@@ -11,13 +11,16 @@ const api_exception_js_1 = require("../api-exception.js");
11
11
  */
12
12
  class MethodNotAllowedError extends api_exception_js_1.ApiException {
13
13
  constructor(response, cause) {
14
- super({
15
- message: (0, i18n_1.translate)('error:METHOD_NOT_ALLOWED', 'Method Not Allowed'),
14
+ super(response, cause);
15
+ this.status = index_js_1.HttpStatus.METHOD_NOT_ALLOWED;
16
+ }
17
+ _initResponse(response) {
18
+ super._initResponse({
19
+ message: (0, i18n_1.translate)('error:METHOD_NOT_ALLOWED'),
16
20
  severity: 'error',
17
21
  code: 'METHOD_NOT_ALLOWED',
18
22
  ...response
19
- }, cause);
20
- this.status = index_js_1.HttpStatus.METHOD_NOT_ALLOWED;
23
+ });
21
24
  }
22
25
  }
23
26
  exports.MethodNotAllowedError = MethodNotAllowedError;
@@ -14,13 +14,16 @@ const api_exception_js_1 = require("../api-exception.js");
14
14
  */
15
15
  class NotFoundError extends api_exception_js_1.ApiException {
16
16
  constructor(response, cause) {
17
- super({
17
+ super(response, cause);
18
+ this.status = index_js_1.HttpStatus.NOT_FOUND;
19
+ }
20
+ _initResponse(response) {
21
+ super._initResponse({
18
22
  message: (0, i18n_1.translate)('error:NOT_FOUND', 'Not found'),
19
23
  severity: 'error',
20
24
  code: 'NOT_FOUND',
21
25
  ...response
22
- }, cause);
23
- this.status = index_js_1.HttpStatus.NOT_FOUND;
26
+ });
24
27
  }
25
28
  }
26
29
  exports.NotFoundError = NotFoundError;
@@ -11,13 +11,16 @@ const api_exception_js_1 = require("../api-exception.js");
11
11
  */
12
12
  class UnauthorizedError extends api_exception_js_1.ApiException {
13
13
  constructor(response, cause) {
14
- super({
14
+ super(response, cause);
15
+ this.status = index_js_1.HttpStatus.UNAUTHORIZED;
16
+ }
17
+ _initResponse(response) {
18
+ super._initResponse({
15
19
  message: (0, i18n_1.translate)('error:UNAUTHORIZED', 'Unauthorized'),
16
20
  severity: 'error',
17
21
  code: 'UNAUTHORIZED',
18
22
  ...response
19
- }, cause);
20
- this.status = index_js_1.HttpStatus.UNAUTHORIZED;
23
+ });
21
24
  }
22
25
  }
23
26
  exports.UnauthorizedError = UnauthorizedError;
@@ -10,13 +10,16 @@ const api_exception_js_1 = require("../api-exception.js");
10
10
  */
11
11
  class UnprocessableEntityError extends api_exception_js_1.ApiException {
12
12
  constructor(response, cause) {
13
- super({
14
- message: (0, i18n_1.translate)('error:UNPROCESSABLE_ENTITY', 'Unprocessable entity'),
13
+ super(response, cause);
14
+ this.status = index_js_1.HttpStatus.UNPROCESSABLE_ENTITY;
15
+ }
16
+ _initResponse(response) {
17
+ super._initResponse({
18
+ message: (0, i18n_1.translate)('error:UNPROCESSABLE_ENTITY'),
15
19
  severity: 'error',
16
20
  code: 'UNPROCESSABLE_ENTITY',
17
21
  ...response
18
- }, cause);
19
- this.status = index_js_1.HttpStatus.UNPROCESSABLE_ENTITY;
22
+ });
20
23
  }
21
24
  }
22
25
  exports.UnprocessableEntityError = UnprocessableEntityError;
@@ -2,10 +2,12 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  const tslib_1 = require("tslib");
4
4
  tslib_1.__exportStar(require("./api-exception.js"), exports);
5
- tslib_1.__exportStar(require("./errors/bad-request.error.js"), exports);
6
- tslib_1.__exportStar(require("./errors/failed-dependency.error.js"), exports);
7
- tslib_1.__exportStar(require("./errors/internal-server.error.js"), exports);
8
- tslib_1.__exportStar(require("./errors/method-not-allowed.error.js"), exports);
9
- tslib_1.__exportStar(require("./errors/not-found.error.js"), exports);
10
- tslib_1.__exportStar(require("./errors/unauthorized.error.js"), exports);
11
- tslib_1.__exportStar(require("./errors/unprocessable-entity.error.js"), exports);
5
+ tslib_1.__exportStar(require("./http-errors/bad-request.error.js"), exports);
6
+ tslib_1.__exportStar(require("./http-errors/failed-dependency.error.js"), exports);
7
+ tslib_1.__exportStar(require("./http-errors/forbidden.error.js"), exports);
8
+ tslib_1.__exportStar(require("./http-errors/internal-server.error.js"), exports);
9
+ tslib_1.__exportStar(require("./http-errors/method-not-allowed.error.js"), exports);
10
+ tslib_1.__exportStar(require("./http-errors/not-found.error.js"), exports);
11
+ tslib_1.__exportStar(require("./http-errors/unauthorized.error.js"), exports);
12
+ tslib_1.__exportStar(require("./http-errors/unprocessable-entity.error.js"), exports);
13
+ tslib_1.__exportStar(require("./resource-errors/resource-conflict.error.js"), exports);
@@ -0,0 +1,19 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.ResourceConflictError = void 0;
4
+ const i18n_1 = require("@opra/i18n");
5
+ const index_js_1 = require("../../enums/index.js");
6
+ const api_exception_js_1 = require("../api-exception.js");
7
+ class ResourceConflictError extends api_exception_js_1.ApiException {
8
+ constructor(resource, fields, cause) {
9
+ super({
10
+ message: (0, i18n_1.translate)(`error:RESOURCE_CONFLICT`, { resource, fields }),
11
+ severity: 'error',
12
+ code: 'RESOURCE_CONFLICT',
13
+ subject: resource,
14
+ location: fields
15
+ }, cause);
16
+ this.status = index_js_1.HttpStatus.CONFLICT;
17
+ }
18
+ }
19
+ exports.ResourceConflictError = ResourceConflictError;
@@ -2,7 +2,7 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.wrapError = void 0;
4
4
  const api_exception_js_1 = require("./api-exception.js");
5
- const internal_server_error_js_1 = require("./errors/internal-server.error.js");
5
+ const internal_server_error_js_1 = require("./http-errors/internal-server.error.js");
6
6
  function wrapError(response) {
7
7
  if (response instanceof api_exception_js_1.ApiException)
8
8
  return response;
@@ -10,7 +10,7 @@ function wrapError(response) {
10
10
  const x = response;
11
11
  if (typeof x.status === 'number' || typeof x.getStatus === 'function')
12
12
  return new api_exception_js_1.ApiException(response);
13
- return new internal_server_error_js_1.InternalServerError(undefined, response);
13
+ return new internal_server_error_js_1.InternalServerError(response);
14
14
  }
15
15
  return new internal_server_error_js_1.InternalServerError();
16
16
  }
@@ -1,38 +1,39 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.OpraAdapter = void 0;
4
+ const strict_typed_events_1 = require("strict-typed-events");
4
5
  const i18n_1 = require("@opra/i18n");
5
6
  const index_js_1 = require("../../exception/index.js");
6
7
  const wrap_error_js_1 = require("../../exception/wrap-error.js");
8
+ const create_i18n_js_1 = require("../../utils/create-i18n.js");
7
9
  class OpraAdapter {
8
10
  service;
9
11
  i18n;
10
- constructor(service, i18n) {
12
+ userContextResolver;
13
+ constructor(service, options) {
11
14
  this.service = service;
12
- this.i18n = i18n || i18n_1.I18n.defaultInstance;
15
+ this.i18n = options?.i18n || i18n_1.I18n.defaultInstance;
16
+ this.userContextResolver = options?.userContext;
13
17
  }
14
- async handler(adapterContext, userContextResolver) {
18
+ async handler(executionContext) {
15
19
  if (!this.i18n.isInitialized)
16
20
  await this.i18n.init();
17
- const executionContexts = [];
18
- let requests;
21
+ let queryContexts;
19
22
  let userContext;
23
+ let failed = false;
20
24
  try {
21
- requests = this.prepareRequests(adapterContext);
25
+ queryContexts = this.prepareRequests(executionContext);
22
26
  let stop = false;
23
27
  // Read requests can be executed simultaneously, write request should be executed one by one
24
28
  let promises;
25
29
  let exclusive = false;
26
- for (const request of requests) {
27
- exclusive = exclusive || request.query.operationType !== 'read';
30
+ for (const context of queryContexts) {
31
+ exclusive = exclusive || context.query.operation !== 'read';
28
32
  // Wait previous read requests before executing update request
29
33
  if (exclusive && promises) {
30
34
  await Promise.allSettled(promises);
31
35
  promises = undefined;
32
36
  }
33
- const resource = request.query.resource;
34
- const context = this.createExecutionContext(adapterContext, request);
35
- executionContexts.push(context);
36
37
  // If previous request in bucket had an error and executed an update
37
38
  // we do not execute next requests
38
39
  if (stop) {
@@ -40,10 +41,14 @@ class OpraAdapter {
40
41
  continue;
41
42
  }
42
43
  try {
44
+ const resource = context.query.resource;
43
45
  const promise = (async () => {
44
46
  await resource.prepare(context);
45
- if (userContextResolver && !userContext)
46
- userContext = userContextResolver(this.isBatch(adapterContext));
47
+ if (this.userContextResolver && !userContext)
48
+ userContext = this.userContextResolver({
49
+ executionContext,
50
+ isBatch: this.isBatch(executionContext)
51
+ });
47
52
  context.userContext = userContext;
48
53
  await resource.execute(context);
49
54
  })().catch(e => {
@@ -69,22 +74,21 @@ class OpraAdapter {
69
74
  }
70
75
  if (promises)
71
76
  await Promise.allSettled(promises);
72
- if (userContext && typeof userContext.onRequestFinish === 'function') {
73
- try {
74
- const hasError = !!executionContexts.find(ctx => ctx.response.errors?.length);
75
- await userContext.onRequestFinish(hasError);
76
- }
77
- catch (e) {
78
- await this.sendError(adapterContext, (0, wrap_error_js_1.wrapError)(e));
79
- return;
80
- }
81
- }
82
- await this.sendResponse(adapterContext, executionContexts);
77
+ await this.sendResponse(executionContext, queryContexts);
83
78
  }
84
79
  catch (e) {
80
+ failed = true;
85
81
  const error = (0, wrap_error_js_1.wrapError)(e);
86
- await this.sendError(adapterContext, error);
87
- return;
82
+ await this.sendError(executionContext, error);
83
+ }
84
+ finally {
85
+ if (executionContext instanceof strict_typed_events_1.AsyncEventEmitter) {
86
+ await executionContext
87
+ .emitAsyncSerial('finish', {
88
+ userContext,
89
+ failed
90
+ }).catch();
91
+ }
88
92
  }
89
93
  }
90
94
  static async initI18n(options) {
@@ -92,9 +96,7 @@ class OpraAdapter {
92
96
  return options.i18n;
93
97
  if (typeof options?.i18n === 'function')
94
98
  return options.i18n();
95
- const instance = i18n_1.I18n.createInstance(options?.i18n);
96
- await instance.init();
97
- return instance;
99
+ return (0, create_i18n_js_1.createI18n)(options?.i18n);
98
100
  }
99
101
  }
100
102
  exports.OpraAdapter = OpraAdapter;
@@ -1,29 +1,60 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.OpraExpressAdapter = void 0;
4
+ const strict_typed_events_1 = require("strict-typed-events");
4
5
  const url_1 = require("@opra/url");
5
6
  const http_adapter_js_1 = require("./http-adapter.js");
6
7
  class OpraExpressAdapter extends http_adapter_js_1.OpraHttpAdapter {
7
8
  static async init(app, service, options) {
8
9
  const i18n = await this.initI18n(options);
9
- const adapter = new OpraExpressAdapter(service, i18n);
10
+ const adapter = new OpraExpressAdapter(service, {
11
+ ...options,
12
+ i18n
13
+ });
10
14
  const prefix = '/' + (0, url_1.normalizePath)(options?.prefix, true);
11
- const userContextResolver = options?.userContext;
12
15
  app.use(prefix, (request, response, next) => {
13
16
  (async () => {
14
- const req = new ExpressRequestWrapper(request);
15
- const res = new ExpressResponseWrapper(response);
16
- const adapterContext = {
17
- getRequest: () => req,
18
- getResponse: () => res
19
- };
20
- await adapter.handler(adapterContext, (isBatch) => userContextResolver && userContextResolver(request, { platform: 'express', isBatch }));
17
+ const executionContext = new ExpressExecutionContext(request, response);
18
+ await adapter.handler(executionContext);
21
19
  })().catch(e => next(e));
22
20
  });
23
21
  return adapter;
24
22
  }
25
23
  }
26
24
  exports.OpraExpressAdapter = OpraExpressAdapter;
25
+ class ExpressExecutionContext extends strict_typed_events_1.AsyncEventEmitter {
26
+ _request;
27
+ _response;
28
+ constructor(request, response) {
29
+ super();
30
+ this._request = new ExpressRequestWrapper(request);
31
+ this._response = new ExpressResponseWrapper(response);
32
+ }
33
+ getType() {
34
+ return 'http';
35
+ }
36
+ getPlatform() {
37
+ return 'express';
38
+ }
39
+ switchToHttp() {
40
+ return this;
41
+ }
42
+ getRequest() {
43
+ return this._request.getInstance();
44
+ }
45
+ getResponse() {
46
+ return this._response.getInstance();
47
+ }
48
+ getRequestWrapper() {
49
+ return this._request;
50
+ }
51
+ getResponseWrapper() {
52
+ return this._response;
53
+ }
54
+ onFinish(fn) {
55
+ this.on('finish', fn);
56
+ }
57
+ }
27
58
  class ExpressRequestWrapper {
28
59
  instance;
29
60
  constructor(instance) {