@opra/core 0.25.5 → 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 (63) hide show
  1. package/cjs/augmentation/container.augmentation.js +2 -0
  2. package/cjs/http/adapters/express-adapter.host.js +34 -0
  3. package/cjs/http/{express-adapter.js → adapters/express-adapter.js} +1 -3
  4. package/cjs/http/{http-adapter.host.js → adapters/node-http-adapter.host.js} +30 -22
  5. package/cjs/http/adapters/node-http-adapter.js +14 -0
  6. package/cjs/http/helpers/json-body-loader.js +29 -0
  7. package/cjs/http/http-adapter-host.js +678 -0
  8. package/cjs/index.js +4 -3
  9. package/cjs/platform-adapter.host.js +74 -45
  10. package/cjs/{endpoint-context.js → request-context.js} +5 -5
  11. package/cjs/request.host.js +3 -0
  12. package/esm/augmentation/container.augmentation.js +1 -0
  13. package/esm/http/adapters/express-adapter.host.js +30 -0
  14. package/esm/http/{express-adapter.js → adapters/express-adapter.js} +1 -3
  15. package/esm/http/{http-adapter.host.js → adapters/node-http-adapter.host.js} +28 -20
  16. package/esm/http/adapters/node-http-adapter.js +11 -0
  17. package/esm/http/helpers/json-body-loader.js +24 -0
  18. package/esm/http/http-adapter-host.js +673 -0
  19. package/esm/index.js +4 -3
  20. package/esm/platform-adapter.host.js +75 -46
  21. package/esm/{endpoint-context.js → request-context.js} +4 -4
  22. package/esm/request.host.js +3 -0
  23. package/i18n/en/error.json +1 -2
  24. package/package.json +3 -3
  25. package/types/augmentation/collection.augmentation.d.ts +19 -16
  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 +13 -9
  29. package/types/augmentation/storage.augmentation.d.ts +11 -14
  30. package/types/http/{express-adapter.d.ts → adapters/express-adapter.d.ts} +3 -3
  31. package/types/http/adapters/express-adapter.host.d.ts +12 -0
  32. package/types/http/{http-adapter.d.ts → adapters/node-http-adapter.d.ts} +5 -5
  33. package/types/http/adapters/node-http-adapter.host.d.ts +19 -0
  34. package/types/http/helpers/json-body-loader.d.ts +5 -0
  35. package/types/http/http-adapter-host.d.ts +34 -0
  36. package/types/index.d.ts +4 -3
  37. package/types/interfaces/request-handler.interface.d.ts +1 -1
  38. package/types/platform-adapter.d.ts +2 -2
  39. package/types/platform-adapter.host.d.ts +18 -14
  40. package/types/{endpoint-context.d.ts → request-context.d.ts} +3 -3
  41. package/types/request.d.ts +7 -2
  42. package/types/request.host.d.ts +5 -2
  43. package/cjs/http/express-adapter.host.js +0 -24
  44. package/cjs/http/http-adapter-base.js +0 -138
  45. package/cjs/http/http-adapter.js +0 -16
  46. package/cjs/http/request-handlers/entity-request-handler.js +0 -429
  47. package/cjs/http/request-handlers/parse-batch-request.js +0 -169
  48. package/cjs/http/request-handlers/request-handler-base.js +0 -37
  49. package/cjs/http/request-handlers/storage-request-handler.js +0 -139
  50. package/esm/http/express-adapter.host.js +0 -20
  51. package/esm/http/http-adapter-base.js +0 -134
  52. package/esm/http/http-adapter.js +0 -13
  53. package/esm/http/request-handlers/entity-request-handler.js +0 -424
  54. package/esm/http/request-handlers/parse-batch-request.js +0 -169
  55. package/esm/http/request-handlers/request-handler-base.js +0 -33
  56. package/esm/http/request-handlers/storage-request-handler.js +0 -134
  57. package/types/http/express-adapter.host.d.ts +0 -11
  58. package/types/http/http-adapter-base.d.ts +0 -23
  59. package/types/http/http-adapter.host.d.ts +0 -18
  60. package/types/http/request-handlers/entity-request-handler.d.ts +0 -24
  61. package/types/http/request-handlers/parse-batch-request.d.ts +0 -0
  62. package/types/http/request-handlers/request-handler-base.d.ts +0 -16
  63. package/types/http/request-handlers/storage-request-handler.d.ts +0 -23
package/types/index.d.ts CHANGED
@@ -1,16 +1,17 @@
1
1
  import "reflect-metadata";
2
2
  import './augmentation/resource.augmentation.js';
3
3
  import './augmentation/collection.augmentation.js';
4
+ import './augmentation/container.augmentation.js';
4
5
  import './augmentation/singleton.augmentation.js';
5
6
  import './augmentation/storage.augmentation.js';
6
7
  export * from './types.js';
7
8
  export * from './execution-context.js';
8
- export * from './endpoint-context.js';
9
+ export * from './request-context.js';
9
10
  export * from './platform-adapter.js';
10
11
  export * from './request.js';
11
12
  export * from './response.js';
12
- export * from './http/express-adapter.js';
13
- export * from './http/http-adapter.js';
13
+ export * from './http/adapters/express-adapter.js';
14
+ export * from './http/adapters/node-http-adapter.js';
14
15
  export * from './http/impl/http-incoming-message.host.js';
15
16
  export * from './http/impl/http-outgoing-message.host.js';
16
17
  export * from './http/http-server-request.js';
@@ -1,4 +1,4 @@
1
1
  import type { ExecutionContext } from '../execution-context.js';
2
2
  export interface RequestHandler {
3
- processRequest(executionContext: ExecutionContext): Promise<void>;
3
+ handleExecution(executionContext: ExecutionContext): Promise<void>;
4
4
  }
@@ -1,8 +1,8 @@
1
1
  import { ApiDocument, FallbackLng, I18n, LanguageResource } from '@opra/common';
2
- import { EndpointContext } from './endpoint-context.js';
3
2
  import { Interceptor } from './interfaces/interceptor.interface.js';
4
3
  import { ILogger } from './interfaces/logger.interface.js';
5
4
  import { RequestHandler } from './interfaces/request-handler.interface.js';
5
+ import { RequestContext } from './request-context.js';
6
6
  export type Protocol = 'http' | 'ws' | 'rpc';
7
7
  export interface PlatformAdapter extends RequestHandler {
8
8
  readonly api: ApiDocument;
@@ -23,7 +23,7 @@ export declare namespace PlatformAdapter {
23
23
  logger?: ILogger;
24
24
  interceptors?: Interceptor[];
25
25
  on?: {
26
- request?: (ctx: EndpointContext) => void | Promise<void>;
26
+ request?: (ctx: RequestContext) => void | Promise<void>;
27
27
  };
28
28
  }
29
29
  interface I18nOptions {
@@ -1,5 +1,5 @@
1
1
  import { AsyncEventEmitter } from 'strict-typed-events';
2
- import { ApiDocument, I18n, Resource } from '@opra/common';
2
+ import { ApiDocument, Endpoint, I18n, Resource } from '@opra/common';
3
3
  import { ExecutionContext } from './execution-context.js';
4
4
  import { Interceptor } from './interfaces/interceptor.interface.js';
5
5
  import type { PlatformAdapter, Protocol } from './platform-adapter.js';
@@ -8,26 +8,30 @@ import { Logger } from './services/logger.js';
8
8
  * @class PlatformAdapterHost
9
9
  */
10
10
  export declare abstract class PlatformAdapterHost extends AsyncEventEmitter implements PlatformAdapter {
11
- readonly api: ApiDocument;
12
- _controllers: WeakMap<Resource, any>;
13
- _protocol: Protocol;
14
- _platform: string;
15
- _initialized: boolean;
16
- _serviceName: string;
17
- _options: PlatformAdapter.Options;
18
- _i18n: I18n;
19
- _logger: Logger;
20
- _interceptors: Interceptor[];
21
- protected constructor(api: ApiDocument, options?: PlatformAdapter.Options);
11
+ protected _api: ApiDocument;
12
+ protected _controllers: Map<Resource, any>;
13
+ protected _protocol: Protocol;
14
+ protected _platform: string;
15
+ protected _serviceName: string;
16
+ protected _i18n: I18n;
17
+ protected _logger: Logger;
18
+ protected _interceptors: Interceptor[];
19
+ get api(): ApiDocument;
22
20
  get platform(): string;
23
21
  get protocol(): Protocol;
24
22
  get serviceName(): string;
23
+ get i18n(): I18n;
25
24
  close(): Promise<void>;
26
25
  /**
27
26
  * Initializes the adapter
28
27
  */
29
- init(): Promise<void>;
28
+ protected init(api: ApiDocument, options?: PlatformAdapter.Options): Promise<void>;
30
29
  getController(resource: Resource | string): Promise<any>;
30
+ getOperationHandler(resource: Resource | string, operationOrAction: string): Promise<{
31
+ endpoint: Endpoint;
32
+ controller: any;
33
+ handler: Function;
34
+ }>;
31
35
  protected _createI18n(options?: PlatformAdapter.I18nOptions): Promise<I18n>;
32
- abstract processRequest(executionContext: ExecutionContext): Promise<void>;
36
+ abstract handleExecution(executionContext: ExecutionContext): Promise<void>;
33
37
  }
@@ -1,10 +1,10 @@
1
1
  import type { ExecutionContext } from './execution-context.js';
2
2
  import type { Request } from './request.js';
3
3
  import type { Response } from './response.js';
4
- export interface EndpointContext<TSession extends {} = {}> extends ExecutionContext<TSession> {
4
+ export interface RequestContext<TSession extends {} = {}> extends ExecutionContext<TSession> {
5
5
  request: Request;
6
6
  response: Response;
7
7
  }
8
- export declare namespace EndpointContext {
9
- function from(executionContext: ExecutionContext, request: Request, response: Response): EndpointContext;
8
+ export declare namespace RequestContext {
9
+ function from(executionContext: ExecutionContext, request: Request, response: Response): RequestContext;
10
10
  }
@@ -1,8 +1,13 @@
1
- import { Resource } from '@opra/common';
1
+ import { Endpoint, Resource } from '@opra/common';
2
2
  import { HttpServerRequest } from './http/http-server-request.js';
3
3
  export interface Request {
4
4
  resource: Resource;
5
- endpoint: string;
5
+ endpoint: Endpoint;
6
+ operation: string;
7
+ key?: any;
8
+ action?: string;
9
+ controller: Object;
10
+ handler: Function;
6
11
  contentId?: string;
7
12
  params: Record<string, any>;
8
13
  switchToHttp(): HttpServerRequest;
@@ -1,9 +1,11 @@
1
1
  import type { PartialSome, StrictOmit } from 'ts-gems';
2
+ import type { Resource } from '@opra/common';
2
3
  import type { HttpServerRequest } from './http/http-server-request.js';
3
4
  import type { Request } from './request.js';
4
5
  export declare namespace RequestHost {
5
- interface Initiator extends PartialSome<StrictOmit<Request, 'switchToHttp' | 'switchToWs' | 'switchToRpc'>, 'params'> {
6
- controller: any;
6
+ interface Initiator extends PartialSome<StrictOmit<Request, 'resource' | 'switchToHttp' | 'switchToWs' | 'switchToRpc'>, 'params'> {
7
+ controller: Object;
8
+ handler: Function;
7
9
  http?: HttpServerRequest;
8
10
  [key: string]: any;
9
11
  }
@@ -16,6 +18,7 @@ export declare class RequestHost implements Request {
16
18
  key?: any;
17
19
  params: Record<string, any>;
18
20
  constructor(init: RequestHost.Initiator);
21
+ get resource(): Resource;
19
22
  switchToHttp(): HttpServerRequest;
20
23
  switchToWs(): never;
21
24
  switchToRpc(): never;
@@ -1,24 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.ExpressAdapterHost = void 0;
4
- const common_1 = require("@opra/common");
5
- const http_adapter_base_js_1 = require("./http-adapter-base.js");
6
- const http_server_request_js_1 = require("./http-server-request.js");
7
- const http_server_response_js_1 = require("./http-server-response.js");
8
- class ExpressAdapterHost extends http_adapter_base_js_1.HttpAdapterBase {
9
- constructor(app, api, options) {
10
- super(api, options);
11
- this._platform = 'express';
12
- const basePath = new common_1.OpraURLPath(options?.basePath);
13
- app.use(basePath.toString(), (_req, _res) => {
14
- const req = http_server_request_js_1.HttpServerRequest.from(_req);
15
- const res = http_server_response_js_1.HttpServerResponse.from(_res);
16
- this.handleIncoming(req, res)
17
- .catch(() => void 0);
18
- });
19
- }
20
- get app() {
21
- return this._app;
22
- }
23
- }
24
- exports.ExpressAdapterHost = ExpressAdapterHost;
@@ -1,138 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.HttpAdapterBase = void 0;
4
- const common_1 = require("@opra/common");
5
- const execution_context_host_js_1 = require("../execution-context.host.js");
6
- const platform_adapter_host_js_1 = require("../platform-adapter.host.js");
7
- const entity_request_handler_js_1 = require("./request-handlers/entity-request-handler.js");
8
- const storage_request_handler_js_1 = require("./request-handlers/storage-request-handler.js");
9
- /**
10
- *
11
- * @class HttpAdapterBase
12
- */
13
- class HttpAdapterBase extends platform_adapter_host_js_1.PlatformAdapterHost {
14
- constructor() {
15
- super(...arguments);
16
- this._protocol = 'http';
17
- this._requestHandlers = [
18
- new entity_request_handler_js_1.EntityRequestHandler(this),
19
- new storage_request_handler_js_1.StorageRequestHandler(this)
20
- ];
21
- }
22
- /**
23
- * Main http request handler
24
- * @param incoming
25
- * @param outgoing
26
- * @protected
27
- */
28
- async handleIncoming(incoming, outgoing) {
29
- const context = new execution_context_host_js_1.ExecutionContextHost(this.api, this.platform, { http: { incoming, outgoing } });
30
- try {
31
- /* istanbul ignore next */
32
- if (!this._initialized)
33
- throw new common_1.InternalServerError(`${Object.getPrototypeOf(this).constructor.name} has not been initialized yet`);
34
- outgoing.setHeader(common_1.HttpHeaderCodes.X_Opra_Version, common_1.OpraSchema.SpecVersion);
35
- // Expose headers if cors enabled
36
- if (outgoing.getHeader(common_1.HttpHeaderCodes.Access_Control_Allow_Origin)) {
37
- // Expose X-Opra-* headers
38
- outgoing.appendHeader(common_1.HttpHeaderCodes.Access_Control_Expose_Headers, Object.values(common_1.HttpHeaderCodes)
39
- .filter(k => k.toLowerCase().startsWith('x-opra-')));
40
- }
41
- let i = 0;
42
- let requestProcessed = false;
43
- const next = async () => {
44
- while (i < this._interceptors.length) {
45
- const interceptor = this._interceptors[i++];
46
- if (interceptor)
47
- await interceptor(context, next);
48
- }
49
- if (!requestProcessed) {
50
- requestProcessed = true;
51
- await this.processRequest(context);
52
- }
53
- };
54
- await next();
55
- }
56
- catch (error) {
57
- context.errors.push((0, common_1.wrapException)(error));
58
- }
59
- // If no response returned to the client we send an error
60
- if (!outgoing.writableEnded) {
61
- if (!context.errors.length)
62
- context.errors.push(new common_1.BadRequestError(`Server can not process this request`));
63
- await this.handleError(context);
64
- }
65
- }
66
- async processRequest(context) {
67
- try {
68
- const { incoming, outgoing } = context.switchToHttp();
69
- if (incoming.method === 'GET' && !incoming.parsedUrl.path.length) {
70
- outgoing.setHeader('content-type', 'application/json');
71
- outgoing.end(JSON.stringify(this.api.exportSchema({ webSafe: true })));
72
- return;
73
- }
74
- const { parsedUrl } = incoming;
75
- if (!parsedUrl.path.length) {
76
- // Batch
77
- if (incoming.headers['content-type'] === 'multipart/mixed') {
78
- // todo
79
- }
80
- throw new common_1.BadRequestError();
81
- }
82
- // Iterate through request handlers until one of them sends response (end outgoing stream)
83
- for (const requestHandler of this._requestHandlers) {
84
- await requestHandler.processRequest(context);
85
- if (outgoing.writableEnded)
86
- return;
87
- if (context.errors.length) {
88
- await this.handleError(context);
89
- return;
90
- }
91
- }
92
- }
93
- finally {
94
- await context.emitAsync('finish');
95
- }
96
- }
97
- async handleError(context) {
98
- const { errors } = context;
99
- const { outgoing } = context.switchToHttp();
100
- if (outgoing.headersSent) {
101
- outgoing.end();
102
- return;
103
- }
104
- errors.forEach(x => {
105
- // todo. implement a better log mechanism
106
- if (x instanceof common_1.OpraException)
107
- this._logger.fatal(x);
108
- else
109
- this._logger.error(x);
110
- });
111
- const wrappedErrors = errors.map(common_1.wrapException);
112
- // Sort errors from fatal to info
113
- wrappedErrors.sort((a, b) => {
114
- const i = common_1.IssueSeverity.Keys.indexOf(a.severity) - common_1.IssueSeverity.Keys.indexOf(b.severity);
115
- if (i === 0)
116
- return b.status - a.status;
117
- return i;
118
- });
119
- let status = outgoing.statusCode || 0;
120
- if (!status || status < Number(common_1.HttpStatusCodes.BAD_REQUEST)) {
121
- status = wrappedErrors[0].status;
122
- if (status < Number(common_1.HttpStatusCodes.BAD_REQUEST))
123
- status = common_1.HttpStatusCodes.INTERNAL_SERVER_ERROR;
124
- }
125
- outgoing.statusCode = status;
126
- const body = {
127
- errors: wrappedErrors.map(x => this._i18n.deep(x.toJSON()))
128
- };
129
- outgoing.setHeader(common_1.HttpHeaderCodes.Content_Type, 'application/opra+json; charset=utf-8');
130
- outgoing.setHeader(common_1.HttpHeaderCodes.Cache_Control, 'no-cache');
131
- outgoing.setHeader(common_1.HttpHeaderCodes.Pragma, 'no-cache');
132
- outgoing.setHeader(common_1.HttpHeaderCodes.Expires, '-1');
133
- outgoing.setHeader(common_1.HttpHeaderCodes.X_Opra_Version, common_1.OpraSchema.SpecVersion);
134
- outgoing.send(JSON.stringify(body));
135
- outgoing.end();
136
- }
137
- }
138
- exports.HttpAdapterBase = HttpAdapterBase;
@@ -1,16 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.HttpAdapter = void 0;
4
- const http_adapter_host_js_1 = require("./http-adapter.host.js");
5
- /**
6
- * @namespace HttpAdapter
7
- */
8
- var HttpAdapter;
9
- (function (HttpAdapter) {
10
- async function create(api, options) {
11
- const adapter = new http_adapter_host_js_1.HttpAdapterHost(api, options);
12
- await adapter.init();
13
- return adapter;
14
- }
15
- HttpAdapter.create = create;
16
- })(HttpAdapter || (exports.HttpAdapter = HttpAdapter = {}));