@opra/core 0.25.4 → 0.26.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.
Files changed (126) hide show
  1. package/cjs/http/adapters/express-adapter.host.js +34 -0
  2. package/cjs/{adapter/http → http/adapters}/express-adapter.js +1 -3
  3. package/cjs/{adapter/http/http-adapter.host.js → http/adapters/node-http-adapter.host.js} +30 -22
  4. package/cjs/http/adapters/node-http-adapter.js +14 -0
  5. package/cjs/http/helpers/json-body-loader.js +29 -0
  6. package/cjs/http/http-adapter-host.js +678 -0
  7. package/cjs/index.js +17 -16
  8. package/cjs/{adapter/platform-adapter.host.js → platform-adapter.host.js} +74 -45
  9. package/cjs/{adapter/endpoint-context.js → request-context.js} +5 -5
  10. package/cjs/{adapter/request.host.js → request.host.js} +3 -0
  11. package/cjs/response.js +2 -0
  12. package/esm/http/adapters/express-adapter.host.js +30 -0
  13. package/esm/{adapter/http → http/adapters}/express-adapter.js +1 -3
  14. package/esm/{adapter/http/http-adapter.host.js → http/adapters/node-http-adapter.host.js} +28 -20
  15. package/esm/http/adapters/node-http-adapter.js +11 -0
  16. package/esm/http/helpers/json-body-loader.js +24 -0
  17. package/esm/http/http-adapter-host.js +673 -0
  18. package/esm/index.js +17 -16
  19. package/esm/platform-adapter.host.js +132 -0
  20. package/esm/{adapter/endpoint-context.js → request-context.js} +4 -4
  21. package/esm/{adapter/request.host.js → request.host.js} +3 -0
  22. package/esm/response.js +1 -0
  23. package/i18n/en/error.json +1 -2
  24. package/package.json +3 -3
  25. package/types/augmentation/collection.augmentation.d.ts +26 -17
  26. package/types/augmentation/container.augmentation.d.ts +13 -0
  27. package/types/augmentation/resource.augmentation.d.ts +2 -2
  28. package/types/augmentation/singleton.augmentation.d.ts +14 -10
  29. package/types/augmentation/storage.augmentation.d.ts +16 -16
  30. package/types/{adapter/execution-context.d.ts → execution-context.d.ts} +3 -3
  31. package/types/{adapter/execution-context.host.d.ts → execution-context.host.d.ts} +1 -1
  32. package/types/{adapter/http → http/adapters}/express-adapter.d.ts +3 -3
  33. package/types/http/adapters/express-adapter.host.d.ts +12 -0
  34. package/types/{adapter/http/http-adapter.d.ts → http/adapters/node-http-adapter.d.ts} +5 -5
  35. package/types/http/adapters/node-http-adapter.host.d.ts +19 -0
  36. package/types/http/helpers/json-body-loader.d.ts +5 -0
  37. package/types/http/http-adapter-host.d.ts +34 -0
  38. package/types/{adapter/http → http}/impl/http-outgoing-message.host.d.ts +1 -1
  39. package/types/index.d.ts +17 -16
  40. package/types/{adapter/interfaces → interfaces}/request-handler.interface.d.ts +1 -1
  41. package/types/{adapter/platform-adapter.d.ts → platform-adapter.d.ts} +2 -2
  42. package/types/platform-adapter.host.d.ts +37 -0
  43. package/types/request-context.d.ts +10 -0
  44. package/types/{adapter/request.d.ts → request.d.ts} +8 -3
  45. package/types/{adapter/request.host.d.ts → request.host.d.ts} +7 -4
  46. package/types/{adapter/response.d.ts → response.d.ts} +1 -1
  47. package/types/{adapter/response.host.d.ts → response.host.d.ts} +2 -2
  48. package/cjs/adapter/http/express-adapter.host.js +0 -24
  49. package/cjs/adapter/http/http-adapter-base.js +0 -138
  50. package/cjs/adapter/http/http-adapter.js +0 -16
  51. package/cjs/adapter/http/request-handlers/entity-request-handler.js +0 -418
  52. package/cjs/adapter/http/request-handlers/parse-batch-request.js +0 -169
  53. package/cjs/adapter/http/request-handlers/request-handler-base.js +0 -27
  54. package/cjs/adapter/http/request-handlers/storage-request-handler.js +0 -133
  55. package/esm/adapter/http/express-adapter.host.js +0 -20
  56. package/esm/adapter/http/http-adapter-base.js +0 -134
  57. package/esm/adapter/http/http-adapter.js +0 -13
  58. package/esm/adapter/http/request-handlers/entity-request-handler.js +0 -413
  59. package/esm/adapter/http/request-handlers/parse-batch-request.js +0 -169
  60. package/esm/adapter/http/request-handlers/request-handler-base.js +0 -23
  61. package/esm/adapter/http/request-handlers/storage-request-handler.js +0 -128
  62. package/esm/adapter/platform-adapter.host.js +0 -103
  63. package/types/adapter/endpoint-context.d.ts +0 -10
  64. package/types/adapter/http/express-adapter.host.d.ts +0 -11
  65. package/types/adapter/http/http-adapter-base.d.ts +0 -23
  66. package/types/adapter/http/http-adapter.host.d.ts +0 -18
  67. package/types/adapter/http/request-handlers/entity-request-handler.d.ts +0 -24
  68. package/types/adapter/http/request-handlers/parse-batch-request.d.ts +0 -0
  69. package/types/adapter/http/request-handlers/request-handler-base.d.ts +0 -15
  70. package/types/adapter/http/request-handlers/storage-request-handler.d.ts +0 -23
  71. package/types/adapter/platform-adapter.host.d.ts +0 -33
  72. /package/cjs/{adapter/execution-context.js → augmentation/container.augmentation.js} +0 -0
  73. /package/cjs/{adapter/execution-context.host.js → execution-context.host.js} +0 -0
  74. /package/cjs/{adapter/interfaces/interceptor.interface.js → execution-context.js} +0 -0
  75. /package/cjs/{adapter/http → http}/helpers/common.js +0 -0
  76. /package/cjs/{adapter/http → http}/helpers/concat-readable.js +0 -0
  77. /package/cjs/{adapter/http → http}/helpers/convert-to-headers.js +0 -0
  78. /package/cjs/{adapter/http → http}/helpers/convert-to-raw-headers.js +0 -0
  79. /package/cjs/{adapter/http → http}/helpers/match-known-fields.js +0 -0
  80. /package/cjs/{adapter/http → http}/helpers/multipart-helper.js +0 -0
  81. /package/cjs/{adapter/http → http}/helpers/query-parsers.js +0 -0
  82. /package/cjs/{adapter/http → http}/http-server-request.js +0 -0
  83. /package/cjs/{adapter/http → http}/http-server-response.js +0 -0
  84. /package/cjs/{adapter/http → http}/impl/http-incoming-message.host.js +0 -0
  85. /package/cjs/{adapter/http → http}/impl/http-outgoing-message.host.js +0 -0
  86. /package/cjs/{adapter/interfaces/logger.interface.js → interfaces/interceptor.interface.js} +0 -0
  87. /package/cjs/{adapter/interfaces/request-handler.interface.js → interfaces/logger.interface.js} +0 -0
  88. /package/cjs/{adapter/platform-adapter.js → interfaces/request-handler.interface.js} +0 -0
  89. /package/cjs/{adapter/request.js → platform-adapter.js} +0 -0
  90. /package/cjs/{adapter/response.js → request.js} +0 -0
  91. /package/cjs/{adapter/response.host.js → response.host.js} +0 -0
  92. /package/cjs/{adapter/services → services}/logger.js +0 -0
  93. /package/esm/{adapter/execution-context.js → augmentation/container.augmentation.js} +0 -0
  94. /package/esm/{adapter/execution-context.host.js → execution-context.host.js} +0 -0
  95. /package/esm/{adapter/interfaces/interceptor.interface.js → execution-context.js} +0 -0
  96. /package/esm/{adapter/http → http}/helpers/common.js +0 -0
  97. /package/esm/{adapter/http → http}/helpers/concat-readable.js +0 -0
  98. /package/esm/{adapter/http → http}/helpers/convert-to-headers.js +0 -0
  99. /package/esm/{adapter/http → http}/helpers/convert-to-raw-headers.js +0 -0
  100. /package/esm/{adapter/http → http}/helpers/match-known-fields.js +0 -0
  101. /package/esm/{adapter/http → http}/helpers/multipart-helper.js +0 -0
  102. /package/esm/{adapter/http → http}/helpers/query-parsers.js +0 -0
  103. /package/esm/{adapter/http → http}/http-server-request.js +0 -0
  104. /package/esm/{adapter/http → http}/http-server-response.js +0 -0
  105. /package/esm/{adapter/http → http}/impl/http-incoming-message.host.js +0 -0
  106. /package/esm/{adapter/http → http}/impl/http-outgoing-message.host.js +0 -0
  107. /package/esm/{adapter/interfaces/logger.interface.js → interfaces/interceptor.interface.js} +0 -0
  108. /package/esm/{adapter/interfaces/request-handler.interface.js → interfaces/logger.interface.js} +0 -0
  109. /package/esm/{adapter/platform-adapter.js → interfaces/request-handler.interface.js} +0 -0
  110. /package/esm/{adapter/request.js → platform-adapter.js} +0 -0
  111. /package/esm/{adapter/response.js → request.js} +0 -0
  112. /package/esm/{adapter/response.host.js → response.host.js} +0 -0
  113. /package/esm/{adapter/services → services}/logger.js +0 -0
  114. /package/types/{adapter/http → http}/helpers/common.d.ts +0 -0
  115. /package/types/{adapter/http → http}/helpers/concat-readable.d.ts +0 -0
  116. /package/types/{adapter/http → http}/helpers/convert-to-headers.d.ts +0 -0
  117. /package/types/{adapter/http → http}/helpers/convert-to-raw-headers.d.ts +0 -0
  118. /package/types/{adapter/http → http}/helpers/match-known-fields.d.ts +0 -0
  119. /package/types/{adapter/http → http}/helpers/multipart-helper.d.ts +0 -0
  120. /package/types/{adapter/http → http}/helpers/query-parsers.d.ts +0 -0
  121. /package/types/{adapter/http → http}/http-server-request.d.ts +0 -0
  122. /package/types/{adapter/http → http}/http-server-response.d.ts +0 -0
  123. /package/types/{adapter/http → http}/impl/http-incoming-message.host.d.ts +0 -0
  124. /package/types/{adapter/interfaces → interfaces}/interceptor.interface.d.ts +0 -0
  125. /package/types/{adapter/interfaces → interfaces}/logger.interface.d.ts +0 -0
  126. /package/types/{adapter/services → services}/logger.d.ts +0 -0
@@ -1,133 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.StorageRequestHandler = void 0;
4
- const tslib_1 = require("tslib");
5
- const promises_1 = tslib_1.__importDefault(require("fs/promises"));
6
- const os_1 = tslib_1.__importDefault(require("os"));
7
- const common_1 = require("@opra/common");
8
- const endpoint_context_js_1 = require("../../endpoint-context.js");
9
- const request_host_js_1 = require("../../request.host.js");
10
- const response_host_js_1 = require("../../response.host.js");
11
- const multipart_helper_js_1 = require("../helpers/multipart-helper.js");
12
- const request_handler_base_js_1 = require("./request-handler-base.js");
13
- /**
14
- * @class StorageRequestHandler
15
- */
16
- class StorageRequestHandler extends request_handler_base_js_1.RequestHandlerBase {
17
- constructor(adapter, options) {
18
- super(adapter);
19
- this.adapter = adapter;
20
- this._uploadDir = options?.uploadDir || os_1.default.tmpdir();
21
- }
22
- async processRequest(executionContext) {
23
- const { incoming, outgoing } = executionContext.switchToHttp();
24
- // Parse incoming message and create Request object
25
- const request = await this.parseRequest(executionContext, incoming);
26
- if (!request)
27
- return;
28
- const response = new response_host_js_1.ResponseHost({ http: outgoing });
29
- const context = endpoint_context_js_1.EndpointContext.from(executionContext, request, response);
30
- await this.callEndpoint(context);
31
- if (response.errors.length) {
32
- context.errors.push(...response.errors);
33
- return;
34
- }
35
- await this.sendResponse(context);
36
- }
37
- async parseRequest(executionContext, incoming) {
38
- const contentId = incoming.headers['content-id'];
39
- const p = incoming.parsedUrl.path[0];
40
- const resource = this.adapter.api.getResource(p.resource);
41
- try {
42
- if (!(resource instanceof common_1.Storage))
43
- return;
44
- switch (incoming.method) {
45
- case 'GET': {
46
- const endpointMeta = await this.assertEndpoint(resource, 'get');
47
- return new request_host_js_1.RequestHost({
48
- controller: endpointMeta.controller,
49
- http: incoming,
50
- resource,
51
- endpoint: 'get',
52
- contentId
53
- });
54
- }
55
- case 'DELETE': {
56
- const endpointMeta = await this.assertEndpoint(resource, 'delete');
57
- return new request_host_js_1.RequestHost({
58
- controller: endpointMeta.controller,
59
- http: incoming,
60
- resource,
61
- endpoint: 'delete',
62
- contentId
63
- });
64
- }
65
- case 'POST': {
66
- const endpointMeta = await this.assertEndpoint(resource, 'post');
67
- await promises_1.default.mkdir(this._uploadDir, { recursive: true });
68
- const multipartIterator = new multipart_helper_js_1.MultipartIterator(incoming, {
69
- ...endpointMeta,
70
- filename: () => this.adapter.serviceName + '_p' + process.pid +
71
- 't' + String(Date.now()).substring(8) + 'r' + (0, common_1.uid)(12)
72
- });
73
- multipartIterator.pause();
74
- // Add an hook to clean up files after request finished
75
- executionContext.on('finish', async () => {
76
- multipartIterator.cancel();
77
- await multipartIterator.deleteFiles().catch(() => void 0);
78
- });
79
- return new request_host_js_1.RequestHost({
80
- controller: endpointMeta.controller,
81
- http: incoming,
82
- resource,
83
- endpoint: 'post',
84
- contentId,
85
- parts: multipartIterator
86
- });
87
- }
88
- }
89
- }
90
- catch (e) {
91
- if (e instanceof common_1.OpraException)
92
- throw e;
93
- throw new common_1.BadRequestError(e);
94
- }
95
- }
96
- async callEndpoint(context) {
97
- const request = context.request;
98
- const { response } = context;
99
- // Call endpoint handler method
100
- let value;
101
- try {
102
- value = await request.controller[request.endpoint].call(request.controller, context);
103
- if (response.value == null)
104
- response.value = value;
105
- }
106
- catch (error) {
107
- response.errors.push(error);
108
- }
109
- }
110
- async sendResponse(context) {
111
- const { response } = context;
112
- const outgoing = response.switchToHttp();
113
- outgoing.statusCode = outgoing.statusCode || common_1.HttpStatusCodes.OK;
114
- if (response.value != null) {
115
- if (typeof response.value === 'string') {
116
- if (!outgoing.hasHeader('content-type'))
117
- outgoing.setHeader('content-type', 'text/plain');
118
- outgoing.send(response.value);
119
- }
120
- else if (Buffer.isBuffer(response.value) || (0, common_1.isReadable)(response.value)) {
121
- if (!outgoing.hasHeader('content-type'))
122
- outgoing.setHeader('content-type', 'application/octet-stream');
123
- outgoing.send(response.value);
124
- }
125
- else {
126
- outgoing.setHeader('content-type', 'application/json; charset=utf-8');
127
- outgoing.send(JSON.stringify(response.value));
128
- }
129
- }
130
- outgoing.end();
131
- }
132
- }
133
- exports.StorageRequestHandler = StorageRequestHandler;
@@ -1,20 +0,0 @@
1
- import { OpraURLPath } from '@opra/common';
2
- import { HttpAdapterBase } from './http-adapter-base.js';
3
- import { HttpServerRequest } from './http-server-request.js';
4
- import { HttpServerResponse } from './http-server-response.js';
5
- export class ExpressAdapterHost extends HttpAdapterBase {
6
- constructor(app, api, options) {
7
- super(api, options);
8
- this._platform = 'express';
9
- const basePath = new OpraURLPath(options?.basePath);
10
- app.use(basePath.toString(), (_req, _res) => {
11
- const req = HttpServerRequest.from(_req);
12
- const res = HttpServerResponse.from(_res);
13
- this.handleIncoming(req, res)
14
- .catch(() => void 0);
15
- });
16
- }
17
- get app() {
18
- return this._app;
19
- }
20
- }
@@ -1,134 +0,0 @@
1
- import { BadRequestError, HttpHeaderCodes, HttpStatusCodes, InternalServerError, IssueSeverity, OpraException, OpraSchema, wrapException } from '@opra/common';
2
- import { ExecutionContextHost } from '../execution-context.host.js';
3
- import { PlatformAdapterHost } from '../platform-adapter.host.js';
4
- import { EntityRequestHandler } from './request-handlers/entity-request-handler.js';
5
- import { StorageRequestHandler } from './request-handlers/storage-request-handler.js';
6
- /**
7
- *
8
- * @class HttpAdapterBase
9
- */
10
- export class HttpAdapterBase extends PlatformAdapterHost {
11
- constructor() {
12
- super(...arguments);
13
- this._protocol = 'http';
14
- this._requestHandlers = [
15
- new EntityRequestHandler(this),
16
- new StorageRequestHandler(this)
17
- ];
18
- }
19
- /**
20
- * Main http request handler
21
- * @param incoming
22
- * @param outgoing
23
- * @protected
24
- */
25
- async handleIncoming(incoming, outgoing) {
26
- const context = new ExecutionContextHost(this.api, this.platform, { http: { incoming, outgoing } });
27
- try {
28
- /* istanbul ignore next */
29
- if (!this._initialized)
30
- throw new InternalServerError(`${Object.getPrototypeOf(this).constructor.name} has not been initialized yet`);
31
- outgoing.setHeader(HttpHeaderCodes.X_Opra_Version, OpraSchema.SpecVersion);
32
- // Expose headers if cors enabled
33
- if (outgoing.getHeader(HttpHeaderCodes.Access_Control_Allow_Origin)) {
34
- // Expose X-Opra-* headers
35
- outgoing.appendHeader(HttpHeaderCodes.Access_Control_Expose_Headers, Object.values(HttpHeaderCodes)
36
- .filter(k => k.toLowerCase().startsWith('x-opra-')));
37
- }
38
- let i = 0;
39
- let requestProcessed = false;
40
- const next = async () => {
41
- while (i < this._interceptors.length) {
42
- const interceptor = this._interceptors[i++];
43
- if (interceptor)
44
- await interceptor(context, next);
45
- }
46
- if (!requestProcessed) {
47
- requestProcessed = true;
48
- await this.processRequest(context);
49
- }
50
- };
51
- await next();
52
- }
53
- catch (error) {
54
- context.errors.push(wrapException(error));
55
- }
56
- // If no response returned to the client we send an error
57
- if (!outgoing.writableEnded) {
58
- if (!context.errors.length)
59
- context.errors.push(new BadRequestError(`Server can not process this request`));
60
- await this.handleError(context);
61
- }
62
- }
63
- async processRequest(context) {
64
- try {
65
- const { incoming, outgoing } = context.switchToHttp();
66
- if (incoming.method === 'GET' && !incoming.parsedUrl.path.length) {
67
- outgoing.setHeader('content-type', 'application/json');
68
- outgoing.end(JSON.stringify(this.api.exportSchema({ webSafe: true })));
69
- return;
70
- }
71
- const { parsedUrl } = incoming;
72
- if (!parsedUrl.path.length) {
73
- // Batch
74
- if (incoming.headers['content-type'] === 'multipart/mixed') {
75
- // todo
76
- }
77
- throw new BadRequestError();
78
- }
79
- // Iterate through request handlers until one of them sends response (end outgoing stream)
80
- for (const requestHandler of this._requestHandlers) {
81
- await requestHandler.processRequest(context);
82
- if (outgoing.writableEnded)
83
- return;
84
- if (context.errors.length) {
85
- await this.handleError(context);
86
- return;
87
- }
88
- }
89
- }
90
- finally {
91
- await context.emitAsync('finish');
92
- }
93
- }
94
- async handleError(context) {
95
- const { errors } = context;
96
- const { outgoing } = context.switchToHttp();
97
- if (outgoing.headersSent) {
98
- outgoing.end();
99
- return;
100
- }
101
- errors.forEach(x => {
102
- // todo. implement a better log mechanism
103
- if (x instanceof OpraException)
104
- this._logger.fatal(x);
105
- else
106
- this._logger.error(x);
107
- });
108
- const wrappedErrors = errors.map(wrapException);
109
- // Sort errors from fatal to info
110
- wrappedErrors.sort((a, b) => {
111
- const i = IssueSeverity.Keys.indexOf(a.severity) - IssueSeverity.Keys.indexOf(b.severity);
112
- if (i === 0)
113
- return b.status - a.status;
114
- return i;
115
- });
116
- let status = outgoing.statusCode || 0;
117
- if (!status || status < Number(HttpStatusCodes.BAD_REQUEST)) {
118
- status = wrappedErrors[0].status;
119
- if (status < Number(HttpStatusCodes.BAD_REQUEST))
120
- status = HttpStatusCodes.INTERNAL_SERVER_ERROR;
121
- }
122
- outgoing.statusCode = status;
123
- const body = {
124
- errors: wrappedErrors.map(x => this._i18n.deep(x.toJSON()))
125
- };
126
- outgoing.setHeader(HttpHeaderCodes.Content_Type, 'application/opra+json; charset=utf-8');
127
- outgoing.setHeader(HttpHeaderCodes.Cache_Control, 'no-cache');
128
- outgoing.setHeader(HttpHeaderCodes.Pragma, 'no-cache');
129
- outgoing.setHeader(HttpHeaderCodes.Expires, '-1');
130
- outgoing.setHeader(HttpHeaderCodes.X_Opra_Version, OpraSchema.SpecVersion);
131
- outgoing.send(JSON.stringify(body));
132
- outgoing.end();
133
- }
134
- }
@@ -1,13 +0,0 @@
1
- import { HttpAdapterHost } from './http-adapter.host.js';
2
- /**
3
- * @namespace HttpAdapter
4
- */
5
- export var HttpAdapter;
6
- (function (HttpAdapter) {
7
- async function create(api, options) {
8
- const adapter = new HttpAdapterHost(api, options);
9
- await adapter.init();
10
- return adapter;
11
- }
12
- HttpAdapter.create = create;
13
- })(HttpAdapter || (HttpAdapter = {}));