@opra/common 1.0.0-beta.2 → 1.0.0-beta.4

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 (105) hide show
  1. package/browser/index.cjs +5 -5
  2. package/browser/index.mjs +5 -5
  3. package/cjs/document/api-document.js +14 -0
  4. package/cjs/document/common/api-base.js +5 -3
  5. package/cjs/document/common/document-node.js +6 -2
  6. package/cjs/document/constants.js +2 -1
  7. package/cjs/document/decorators/http-controller.decorator.js +1 -1
  8. package/cjs/document/decorators/http-operation-entity.decorator.js +1 -1
  9. package/cjs/document/decorators/http-operation.decorator.js +5 -5
  10. package/cjs/document/decorators/rpc-controller.decorator.js +69 -0
  11. package/cjs/document/decorators/rpc-operation.decorator.js +80 -0
  12. package/cjs/document/factory/api-document.factory.js +9 -3
  13. package/cjs/document/factory/data-type.factory.js +20 -0
  14. package/cjs/document/factory/http-api.factory.js +50 -77
  15. package/cjs/document/factory/rpc-api.factory.js +202 -0
  16. package/cjs/document/http/http-api.js +5 -4
  17. package/cjs/document/http/http-controller.js +16 -0
  18. package/cjs/document/http/http-operation.js +6 -0
  19. package/cjs/document/index.js +8 -0
  20. package/cjs/document/rpc/rpc-api.js +54 -0
  21. package/cjs/document/rpc/rpc-controller.js +116 -0
  22. package/cjs/document/rpc/rpc-header.js +40 -0
  23. package/cjs/document/rpc/rpc-operation-response.js +58 -0
  24. package/cjs/document/rpc/rpc-operation.js +80 -0
  25. package/cjs/enums/index.js +7 -0
  26. package/cjs/exception/http-errors/forbidden.error.js +1 -1
  27. package/cjs/exception/http-errors/resource-not.available.error.js +1 -1
  28. package/cjs/index.js +1 -1
  29. package/cjs/schema/opra-schema.js +3 -0
  30. package/cjs/schema/rpc/rpc-controller.interface.js +11 -0
  31. package/cjs/schema/rpc/rpc-header.interface.js +2 -0
  32. package/cjs/schema/rpc/rpc-operation.interface.js +7 -0
  33. package/esm/document/api-document.js +14 -0
  34. package/esm/document/common/api-base.js +5 -3
  35. package/esm/document/common/document-node.js +6 -2
  36. package/esm/document/constants.js +1 -0
  37. package/esm/document/decorators/http-controller.decorator.js +1 -1
  38. package/esm/document/decorators/http-operation-entity.decorator.js +1 -1
  39. package/esm/document/decorators/http-operation.decorator.js +5 -5
  40. package/esm/document/decorators/rpc-controller.decorator.js +65 -0
  41. package/esm/document/decorators/rpc-operation.decorator.js +76 -0
  42. package/esm/document/factory/api-document.factory.js +9 -3
  43. package/esm/document/factory/data-type.factory.js +20 -0
  44. package/esm/document/factory/http-api.factory.js +50 -77
  45. package/esm/document/factory/rpc-api.factory.js +198 -0
  46. package/esm/document/http/http-api.js +5 -4
  47. package/esm/document/http/http-controller.js +17 -1
  48. package/esm/document/http/http-operation.js +6 -0
  49. package/esm/document/index.js +8 -0
  50. package/esm/document/rpc/rpc-api.js +50 -0
  51. package/esm/document/rpc/rpc-controller.js +113 -0
  52. package/esm/document/rpc/rpc-header.js +37 -0
  53. package/esm/document/rpc/rpc-operation-response.js +54 -0
  54. package/esm/document/rpc/rpc-operation.js +77 -0
  55. package/esm/enums/index.js +4 -0
  56. package/esm/exception/http-errors/forbidden.error.js +1 -1
  57. package/esm/exception/http-errors/resource-not.available.error.js +1 -1
  58. package/esm/index.js +1 -1
  59. package/esm/schema/opra-schema.js +3 -0
  60. package/esm/schema/rpc/rpc-controller.interface.js +8 -0
  61. package/esm/schema/rpc/rpc-header.interface.js +1 -0
  62. package/esm/schema/rpc/rpc-operation.interface.js +4 -0
  63. package/package.json +2 -2
  64. package/types/document/api-document.d.ts +5 -2
  65. package/types/document/common/api-base.d.ts +3 -2
  66. package/types/document/constants.d.ts +1 -0
  67. package/types/document/decorators/http-operation.decorator.d.ts +3 -3
  68. package/types/document/decorators/rpc-controller.decorator.d.ts +20 -0
  69. package/types/document/decorators/rpc-operation.decorator.d.ts +32 -0
  70. package/types/document/factory/api-document.factory.d.ts +2 -1
  71. package/types/document/factory/data-type.factory.d.ts +1 -0
  72. package/types/document/factory/http-api.factory.d.ts +10 -6
  73. package/types/document/factory/rpc-api.factory.d.ts +40 -0
  74. package/types/document/http/http-api.d.ts +8 -3
  75. package/types/document/http/http-controller.d.ts +8 -2
  76. package/types/document/index.d.ts +11 -0
  77. package/types/document/rpc/rpc-api.d.ts +27 -0
  78. package/types/document/rpc/rpc-controller.d.ts +89 -0
  79. package/types/document/rpc/rpc-header.d.ts +47 -0
  80. package/types/document/rpc/rpc-operation-response.d.ts +41 -0
  81. package/types/document/rpc/rpc-operation.d.ts +77 -0
  82. package/types/enums/index.d.ts +4 -0
  83. package/types/exception/http-errors/forbidden.error.d.ts +1 -1
  84. package/types/index.d.cts +1 -1
  85. package/types/index.d.ts +1 -1
  86. package/types/schema/api-document.interface.d.ts +25 -4
  87. package/types/schema/opra-schema.d.ts +3 -0
  88. package/types/schema/rpc/rpc-controller.interface.d.ts +22 -0
  89. package/types/schema/rpc/rpc-header.interface.d.ts +19 -0
  90. package/types/schema/rpc/rpc-operation.interface.d.ts +26 -0
  91. package/cjs/http/index.js +0 -7
  92. package/esm/http/index.js +0 -4
  93. package/types/http/index.d.ts +0 -4
  94. /package/cjs/{http/enums → enums}/http-headers-codes.enum.js +0 -0
  95. /package/cjs/{http/enums → enums}/http-status-codes.enum.js +0 -0
  96. /package/cjs/{http/enums → enums}/http-status-messages.js +0 -0
  97. /package/cjs/{http/enums → enums}/mime-types.enum.js +0 -0
  98. /package/esm/{http/enums → enums}/http-headers-codes.enum.js +0 -0
  99. /package/esm/{http/enums → enums}/http-status-codes.enum.js +0 -0
  100. /package/esm/{http/enums → enums}/http-status-messages.js +0 -0
  101. /package/esm/{http/enums → enums}/mime-types.enum.js +0 -0
  102. /package/types/{http/enums → enums}/http-headers-codes.enum.d.ts +0 -0
  103. /package/types/{http/enums → enums}/http-status-codes.enum.d.ts +0 -0
  104. /package/types/{http/enums → enums}/http-status-messages.d.ts +0 -0
  105. /package/types/{http/enums → enums}/mime-types.enum.d.ts +0 -0
@@ -0,0 +1,198 @@
1
+ import { isConstructor, resolveThunk } from '../../helpers/index.js';
2
+ import { RPC_CONTROLLER_METADATA } from '../constants.js';
3
+ import { RpcApi } from '../rpc/rpc-api.js';
4
+ import { RpcController } from '../rpc/rpc-controller.js';
5
+ import { RpcHeader } from '../rpc/rpc-header.js';
6
+ import { RpcOperation } from '../rpc/rpc-operation.js';
7
+ import { RpcOperationResponse } from '../rpc/rpc-operation-response.js';
8
+ import { DataTypeFactory } from './data-type.factory.js';
9
+ /**
10
+ * @class RpcApiFactory
11
+ */
12
+ export class RpcApiFactory {
13
+ /**
14
+ * Generates RpcApi
15
+ * @param context
16
+ * @param init
17
+ */
18
+ static async createApi(context, init) {
19
+ const api = new RpcApi(init);
20
+ if (init.controllers) {
21
+ await context.enterAsync('.controllers', async () => {
22
+ if (Array.isArray(init.controllers)) {
23
+ for (const c of init.controllers) {
24
+ const controller = await this._createController(context, api, c);
25
+ if (controller)
26
+ api.controllers.set(controller.name, controller);
27
+ }
28
+ }
29
+ else {
30
+ for (const [k, v] of Object.entries(init.controllers)) {
31
+ const controller = await this._createController(context, api, v, k);
32
+ if (controller)
33
+ api.controllers.set(controller.name, controller);
34
+ }
35
+ }
36
+ });
37
+ }
38
+ return api;
39
+ }
40
+ static async _createController(context, parent, thunk, name) {
41
+ if (typeof thunk === 'function' && !isConstructor(thunk)) {
42
+ thunk = thunk();
43
+ }
44
+ thunk = await resolveThunk(thunk);
45
+ let ctor;
46
+ let metadata;
47
+ let instance;
48
+ // If thunk is a class
49
+ if (typeof thunk === 'function') {
50
+ metadata = Reflect.getMetadata(RPC_CONTROLLER_METADATA, thunk);
51
+ if (!metadata)
52
+ return context.addError(`Class "${thunk.name}" doesn't have a valid RpcController metadata`);
53
+ ctor = thunk;
54
+ }
55
+ else {
56
+ // If thunk is an instance of a class decorated with RpcController()
57
+ ctor = Object.getPrototypeOf(thunk).constructor;
58
+ metadata = Reflect.getMetadata(RPC_CONTROLLER_METADATA, ctor);
59
+ if (metadata)
60
+ instance = thunk;
61
+ else {
62
+ // If thunk is a DecoratorMetadata or InitArguments
63
+ metadata = thunk;
64
+ if (thunk.instance === 'object') {
65
+ instance = thunk.instance;
66
+ ctor = Object.getPrototypeOf(instance).constructor;
67
+ }
68
+ }
69
+ }
70
+ if (!metadata)
71
+ return context.addError(`Class "${ctor.name}" is not decorated with RpcController()`);
72
+ name = name || metadata.name;
73
+ if (!name)
74
+ throw new TypeError(`Controller name required`);
75
+ const controller = new RpcController(parent, {
76
+ ...metadata,
77
+ name,
78
+ instance,
79
+ ctor,
80
+ });
81
+ if (metadata.types) {
82
+ await context.enterAsync('.types', async () => {
83
+ await DataTypeFactory.addDataTypes(context, controller, metadata.types);
84
+ });
85
+ }
86
+ if (metadata.headers) {
87
+ await context.enterAsync('.headers', async () => {
88
+ let i = 0;
89
+ for (const v of metadata.headers) {
90
+ await context.enterAsync(`[${i++}]`, async () => {
91
+ const prmArgs = { ...v };
92
+ await context.enterAsync('.type', async () => {
93
+ if (v.type)
94
+ prmArgs.type = controller.node.findDataType(v.type);
95
+ if (!prmArgs.type && typeof v.type === 'object') {
96
+ prmArgs.type = await DataTypeFactory.createDataType(context, controller, v.type);
97
+ }
98
+ if (!prmArgs.type)
99
+ prmArgs.type = controller.node.getDataType('any');
100
+ });
101
+ const prm = new RpcHeader(controller, prmArgs);
102
+ controller.headers.push(prm);
103
+ });
104
+ }
105
+ });
106
+ }
107
+ if (metadata.operations) {
108
+ await context.enterAsync('.operations', async () => {
109
+ for (const [operationName, operationMeta] of Object.entries(metadata.operations)) {
110
+ await context.enterAsync(`[${operationName}]`, async () => {
111
+ const operation = new RpcOperation(controller, {
112
+ ...operationMeta,
113
+ name: operationName,
114
+ types: undefined,
115
+ payloadType: undefined,
116
+ keyType: undefined,
117
+ });
118
+ await this._initRpcOperation(context, operation, operationMeta);
119
+ controller.operations.set(operation.name, operation);
120
+ });
121
+ }
122
+ });
123
+ }
124
+ return controller;
125
+ }
126
+ /**
127
+ * Initializes RpcOperation
128
+ * @param context
129
+ * @param operation
130
+ * @param metadata
131
+ * @protected
132
+ */
133
+ static async _initRpcOperation(context, operation, metadata) {
134
+ if (metadata.types) {
135
+ await context.enterAsync('.types', async () => {
136
+ await DataTypeFactory.addDataTypes(context, operation, metadata.types);
137
+ });
138
+ }
139
+ operation.payloadType = await DataTypeFactory.resolveDataType(context, operation, metadata.payloadType);
140
+ if (metadata.keyType) {
141
+ operation.keyType = await DataTypeFactory.resolveDataType(context, operation, metadata.keyType);
142
+ }
143
+ if (metadata.headers) {
144
+ await context.enterAsync('.headers', async () => {
145
+ let i = 0;
146
+ for (const v of metadata.headers) {
147
+ await context.enterAsync(`[${i++}]`, async () => {
148
+ const prmArgs = { ...v };
149
+ await context.enterAsync('.type', async () => {
150
+ prmArgs.type = await DataTypeFactory.resolveDataType(context, operation, v.type);
151
+ });
152
+ const prm = new RpcHeader(operation, prmArgs);
153
+ operation.headers.push(prm);
154
+ });
155
+ }
156
+ });
157
+ }
158
+ if (metadata.response) {
159
+ await context.enterAsync('.response', async () => {
160
+ const response = new RpcOperationResponse(operation, {
161
+ ...metadata.response,
162
+ payloadType: undefined,
163
+ keyType: undefined,
164
+ });
165
+ await this._initRpcOperationResponse(context, response, metadata.response);
166
+ operation.response = response;
167
+ });
168
+ }
169
+ }
170
+ /**
171
+ * Initializes RpcOperationResponse
172
+ * @param context
173
+ * @param response
174
+ * @param metadata
175
+ * @protected
176
+ */
177
+ static async _initRpcOperationResponse(context, response, metadata) {
178
+ response.payloadType = await DataTypeFactory.resolveDataType(context, response, metadata.payloadType);
179
+ if (metadata.keyType) {
180
+ response.keyType = await DataTypeFactory.resolveDataType(context, response, metadata.keyType);
181
+ }
182
+ if (metadata.headers) {
183
+ await context.enterAsync('.headers', async () => {
184
+ let i = 0;
185
+ for (const v of metadata.headers) {
186
+ await context.enterAsync(`[${i++}]`, async () => {
187
+ const prmArgs = { ...v };
188
+ await context.enterAsync('.type', async () => {
189
+ prmArgs.type = await DataTypeFactory.resolveDataType(context, response, v.type);
190
+ });
191
+ const prm = new RpcHeader(response, prmArgs);
192
+ response.headers.push(prm);
193
+ });
194
+ }
195
+ });
196
+ }
197
+ }
198
+ }
@@ -5,12 +5,13 @@ import { HttpController } from './http-controller.js';
5
5
  * @class HttpApi
6
6
  */
7
7
  export class HttpApi extends ApiBase {
8
- constructor(owner) {
9
- super(owner);
8
+ constructor(init) {
9
+ super(init);
10
10
  // noinspection JSUnusedGlobalSymbols
11
11
  this._controllerReverseMap = new WeakMap();
12
- this.protocol = 'http';
12
+ this.transport = 'http';
13
13
  this.controllers = new ResponsiveMap();
14
+ this.url = init.url;
14
15
  }
15
16
  findController(arg0) {
16
17
  return HttpController.prototype.findController.call(this, arg0);
@@ -23,7 +24,7 @@ export class HttpApi extends ApiBase {
23
24
  const schema = super.toJSON();
24
25
  const out = {
25
26
  ...schema,
26
- protocol: this.protocol,
27
+ transport: this.transport,
27
28
  url: this.url,
28
29
  controllers: {},
29
30
  };
@@ -4,7 +4,7 @@ import { omitUndefined, ResponsiveMap } from '../../helpers/index.js';
4
4
  import { OpraSchema } from '../../schema/index.js';
5
5
  import { DataTypeMap } from '../common/data-type-map.js';
6
6
  import { DocumentElement } from '../common/document-element.js';
7
- import { CLASS_NAME_PATTERN, DECORATOR, kDataTypeMap } from '../constants.js';
7
+ import { CLASS_NAME_PATTERN, DECORATOR, HTTP_CONTROLLER_METADATA, kDataTypeMap } from '../constants.js';
8
8
  import { HttpControllerDecoratorFactory } from '../decorators/http-controller.decorator.js';
9
9
  import { colorFgMagenta, colorFgYellow, colorReset, nodeInspectCustom } from '../utils/inspect.util.js';
10
10
  /**
@@ -32,6 +32,8 @@ export const HttpController = function (...args) {
32
32
  _this.ctor = initArgs.ctor;
33
33
  _this._controllerReverseMap = new WeakMap();
34
34
  _this._initialize?.(initArgs);
35
+ _this.onInit = initArgs.onInit;
36
+ _this.onShutdown = initArgs.onShutdown;
35
37
  };
36
38
  /**
37
39
  *
@@ -151,3 +153,17 @@ class HttpControllerClass extends DocumentElement {
151
153
  HttpController.prototype = HttpControllerClass.prototype;
152
154
  Object.assign(HttpController, HttpControllerDecoratorFactory);
153
155
  HttpController[DECORATOR] = HttpControllerDecoratorFactory;
156
+ HttpController.OnInit = function () {
157
+ return (target, propertyKey) => {
158
+ const sourceMetadata = (Reflect.getOwnMetadata(HTTP_CONTROLLER_METADATA, target.constructor) || {});
159
+ sourceMetadata.onInit = target[propertyKey];
160
+ Reflect.defineMetadata(HTTP_CONTROLLER_METADATA, target.constructor, sourceMetadata);
161
+ };
162
+ };
163
+ HttpController.OnShutdown = function () {
164
+ return (target, propertyKey) => {
165
+ const sourceMetadata = (Reflect.getOwnMetadata(HTTP_CONTROLLER_METADATA, target.constructor) || {});
166
+ sourceMetadata.onShutdown = target[propertyKey];
167
+ Reflect.defineMetadata(HTTP_CONTROLLER_METADATA, target.constructor, sourceMetadata);
168
+ };
169
+ };
@@ -74,6 +74,12 @@ class HttpOperationClass extends DocumentElement {
74
74
  composition: this.composition,
75
75
  requestBody: this.requestBody?.toJSON(),
76
76
  });
77
+ if (this.types.size) {
78
+ out.types = {};
79
+ for (const v of this.types.values()) {
80
+ out.types[v.name] = v.toJSON();
81
+ }
82
+ }
77
83
  if (this.parameters.length) {
78
84
  out.parameters = [];
79
85
  for (const prm of this.parameters) {
@@ -1,4 +1,6 @@
1
1
  import 'reflect-metadata';
2
+ import * as RpcControllerDecorator_ from './decorators/rpc-controller.decorator.js';
3
+ import * as RpcOperationDecorator_ from './decorators/rpc-operation.decorator.js';
2
4
  import * as DataTypeFactory_ from './factory/data-type.factory.js';
3
5
  import * as HttpApiFactory_ from './factory/http-api.factory.js';
4
6
  export * from './api-document.js';
@@ -33,8 +35,14 @@ export * from './http/http-operation-response.js';
33
35
  export * from './http/http-parameter.js';
34
36
  export * from './http/http-request-body.js';
35
37
  export * from './http/http-status-range.js';
38
+ export * from './rpc/rpc-api.js';
39
+ export * from './rpc/rpc-controller.js';
40
+ export * from './rpc/rpc-header.js';
41
+ export * from './rpc/rpc-operation.js';
36
42
  export var classes;
37
43
  (function (classes) {
38
44
  classes.HttpApiFactory = HttpApiFactory_.HttpApiFactory;
39
45
  classes.DataTypeFactory = DataTypeFactory_.DataTypeFactory;
46
+ classes.RpcOperationDecoratorFactory = RpcOperationDecorator_.RpcOperationDecoratorFactory;
47
+ classes.RpcControllerDecoratorFactory = RpcControllerDecorator_.RpcControllerDecoratorFactory;
40
48
  })(classes || (classes = {}));
@@ -0,0 +1,50 @@
1
+ import { ResponsiveMap } from '../../helpers/index.js';
2
+ import { ApiBase } from '../common/api-base.js';
3
+ /**
4
+ * @class RpcApi
5
+ */
6
+ export class RpcApi extends ApiBase {
7
+ constructor(init) {
8
+ super(init);
9
+ // noinspection JSUnusedGlobalSymbols
10
+ this._controllerReverseMap = new WeakMap();
11
+ this.transport = 'rpc';
12
+ this.controllers = new ResponsiveMap();
13
+ this.platform = init.platform;
14
+ }
15
+ findController(arg0) {
16
+ if (typeof arg0 === 'function') {
17
+ /** Check for cached mapping */
18
+ const controller = this._controllerReverseMap.get(arg0);
19
+ if (controller != null)
20
+ return controller;
21
+ /** Lookup for ctor in all controllers */
22
+ for (const c of this.controllers.values()) {
23
+ if (c.ctor === arg0) {
24
+ this._controllerReverseMap.set(arg0, c);
25
+ return c;
26
+ }
27
+ }
28
+ this._controllerReverseMap.set(arg0, null);
29
+ return;
30
+ }
31
+ return this.controllers.get(arg0);
32
+ }
33
+ findOperation(arg0, operationName) {
34
+ const controller = this.findController(arg0);
35
+ return controller?.operations.get(operationName);
36
+ }
37
+ toJSON() {
38
+ const schema = super.toJSON();
39
+ const out = {
40
+ ...schema,
41
+ transport: this.transport,
42
+ platform: this.platform,
43
+ controllers: {},
44
+ };
45
+ for (const v of this.controllers.values()) {
46
+ out.controllers[v.name] = v.toJSON();
47
+ }
48
+ return out;
49
+ }
50
+ }
@@ -0,0 +1,113 @@
1
+ import { asMutable } from 'ts-gems';
2
+ import { omitUndefined, ResponsiveMap } from '../../helpers/index.js';
3
+ import { OpraSchema } from '../../schema/index.js';
4
+ import { DataTypeMap } from '../common/data-type-map.js';
5
+ import { DocumentElement } from '../common/document-element.js';
6
+ import { CLASS_NAME_PATTERN, DECORATOR, kDataTypeMap, RPC_CONTROLLER_METADATA } from '../constants.js';
7
+ import { RpcControllerDecoratorFactory } from '../decorators/rpc-controller.decorator.js';
8
+ import { colorFgMagenta, colorFgYellow, colorReset, nodeInspectCustom } from '../utils/inspect.util.js';
9
+ /**
10
+ * RpcController
11
+ */
12
+ export const RpcController = function (...args) {
13
+ // ClassDecorator
14
+ if (!this)
15
+ return RpcController[DECORATOR].apply(undefined, args);
16
+ // Constructor
17
+ const [owner, initArgs] = args;
18
+ DocumentElement.call(this, owner);
19
+ if (!CLASS_NAME_PATTERN.test(initArgs.name))
20
+ throw new TypeError(`Invalid resource name (${initArgs.name})`);
21
+ const _this = asMutable(this);
22
+ _this.kind = OpraSchema.RpcController.Kind;
23
+ _this.types = _this.node[kDataTypeMap] = new DataTypeMap();
24
+ _this.operations = new ResponsiveMap();
25
+ _this.headers = [];
26
+ _this.name = initArgs.name;
27
+ _this.description = initArgs.description;
28
+ _this.instance = initArgs.instance;
29
+ _this.ctor = initArgs.ctor;
30
+ _this._controllerReverseMap = new WeakMap();
31
+ _this._initialize?.(initArgs);
32
+ _this.onInit = initArgs.onInit;
33
+ _this.onShutdown = initArgs.onShutdown;
34
+ };
35
+ /**
36
+ *
37
+ * @class RpcController
38
+ */
39
+ class RpcControllerClass extends DocumentElement {
40
+ findHeader(paramName, location) {
41
+ const paramNameLower = paramName.toLowerCase();
42
+ let prm;
43
+ for (prm of this.headers) {
44
+ if (typeof prm.name === 'string') {
45
+ prm._nameLower = prm._nameLower || prm.name.toLowerCase();
46
+ if (prm._nameLower === paramNameLower)
47
+ return prm;
48
+ }
49
+ if (prm.name instanceof RegExp && prm.name.test(paramName))
50
+ return prm;
51
+ }
52
+ if (this.node.parent && this.node.parent.element instanceof RpcController) {
53
+ return this.node.parent.element.findHeader(paramName, location);
54
+ }
55
+ }
56
+ /**
57
+ *
58
+ */
59
+ toString() {
60
+ return `[RpcController ${this.name}]`;
61
+ }
62
+ /**
63
+ *
64
+ */
65
+ toJSON() {
66
+ const out = omitUndefined({
67
+ kind: this.kind,
68
+ description: this.description,
69
+ });
70
+ if (this.operations.size) {
71
+ out.operations = {};
72
+ for (const v of this.operations.values()) {
73
+ out.operations[v.name] = v.toJSON();
74
+ }
75
+ }
76
+ if (this.types.size) {
77
+ out.types = {};
78
+ for (const v of this.types.values()) {
79
+ out.types[v.name] = v.toJSON();
80
+ }
81
+ }
82
+ if (this.headers.length) {
83
+ out.headers = [];
84
+ for (const prm of this.headers) {
85
+ out.headers.push(prm.toJSON());
86
+ }
87
+ }
88
+ return out;
89
+ }
90
+ /**
91
+ *
92
+ */
93
+ [nodeInspectCustom]() {
94
+ return `[${colorFgYellow}RpcController${colorFgMagenta + this.name + colorReset}]`;
95
+ }
96
+ }
97
+ RpcController.prototype = RpcControllerClass.prototype;
98
+ Object.assign(RpcController, RpcControllerDecoratorFactory);
99
+ RpcController[DECORATOR] = RpcControllerDecoratorFactory;
100
+ RpcController.OnInit = function () {
101
+ return (target, propertyKey) => {
102
+ const sourceMetadata = (Reflect.getOwnMetadata(RPC_CONTROLLER_METADATA, target.constructor) || {});
103
+ sourceMetadata.onInit = target[propertyKey];
104
+ Reflect.defineMetadata(RPC_CONTROLLER_METADATA, target.constructor, sourceMetadata);
105
+ };
106
+ };
107
+ RpcController.OnShutdown = function () {
108
+ return (target, propertyKey) => {
109
+ const sourceMetadata = (Reflect.getOwnMetadata(RPC_CONTROLLER_METADATA, target.constructor) || {});
110
+ sourceMetadata.onShutdown = target[propertyKey];
111
+ Reflect.defineMetadata(RPC_CONTROLLER_METADATA, target.constructor, sourceMetadata);
112
+ };
113
+ };
@@ -0,0 +1,37 @@
1
+ import { asMutable } from 'ts-gems';
2
+ import { omitUndefined } from '../../helpers/index.js';
3
+ import { Value } from '../common/value.js';
4
+ import { parseRegExp } from '../utils/parse-regexp.util.js';
5
+ export const RpcHeader = function (owner, initArgs) {
6
+ if (!this)
7
+ throw new TypeError('"this" should be passed to call class constructor');
8
+ Value.call(this, owner, initArgs);
9
+ const _this = asMutable(this);
10
+ if (initArgs.name) {
11
+ _this.name =
12
+ initArgs.name instanceof RegExp
13
+ ? initArgs.name
14
+ : initArgs.name.startsWith('/')
15
+ ? parseRegExp(initArgs.name, {
16
+ includeFlags: 'i',
17
+ excludeFlags: 'm',
18
+ })
19
+ : initArgs.name;
20
+ }
21
+ _this.deprecated = initArgs.deprecated;
22
+ _this.required = initArgs.required;
23
+ };
24
+ /**
25
+ * @class RpcHeader
26
+ */
27
+ class RpcHeaderClass extends Value {
28
+ toJSON() {
29
+ return omitUndefined({
30
+ ...super.toJSON(),
31
+ name: this.name,
32
+ required: this.required,
33
+ deprecated: this.deprecated,
34
+ });
35
+ }
36
+ }
37
+ RpcHeader.prototype = RpcHeaderClass.prototype;
@@ -0,0 +1,54 @@
1
+ import { omitUndefined } from '../../helpers/index.js';
2
+ import { DocumentElement } from '../common/document-element.js';
3
+ import { DataType } from '../data-type/data-type.js';
4
+ /**
5
+ * @class RpcOperationResponse
6
+ */
7
+ export class RpcOperationResponse extends DocumentElement {
8
+ constructor(owner, initArgs) {
9
+ super(owner);
10
+ this.headers = [];
11
+ this.channel = initArgs?.channel;
12
+ this.description = initArgs?.description;
13
+ if (initArgs?.payloadType) {
14
+ this.payloadType =
15
+ initArgs?.payloadType instanceof DataType
16
+ ? initArgs.payloadType
17
+ : this.owner.node.getDataType(initArgs.payloadType);
18
+ }
19
+ else
20
+ this.payloadType = this.owner.node.getDataType('any');
21
+ if (initArgs?.keyType) {
22
+ this.keyType =
23
+ initArgs?.keyType instanceof DataType ? initArgs.keyType : this.owner.node.getDataType(initArgs.keyType);
24
+ }
25
+ }
26
+ findHeader(paramName) {
27
+ const paramNameLower = paramName.toLowerCase();
28
+ let prm;
29
+ for (prm of this.headers) {
30
+ if (typeof prm.name === 'string') {
31
+ prm._nameLower = prm._nameLower || prm.name.toLowerCase();
32
+ if (prm._nameLower === paramNameLower)
33
+ return prm;
34
+ }
35
+ if (prm.name instanceof RegExp && prm.name.test(paramName))
36
+ return prm;
37
+ }
38
+ }
39
+ toJSON() {
40
+ const out = omitUndefined({
41
+ description: this.description,
42
+ channel: this.channel,
43
+ payloadType: this.payloadType.name ? this.payloadType.name : this.payloadType.toJSON(),
44
+ keyType: this.keyType ? (this.keyType.name ? this.keyType.name : this.keyType.toJSON()) : undefined,
45
+ });
46
+ if (this.headers.length) {
47
+ out.headers = [];
48
+ for (const prm of this.headers) {
49
+ out.headers.push(prm.toJSON());
50
+ }
51
+ }
52
+ return out;
53
+ }
54
+ }
@@ -0,0 +1,77 @@
1
+ import { asMutable } from 'ts-gems';
2
+ import { omitUndefined } from '../../helpers/index.js';
3
+ import { OpraSchema } from '../../schema/index.js';
4
+ import { DataTypeMap } from '../common/data-type-map.js';
5
+ import { DocumentElement } from '../common/document-element.js';
6
+ import { CLASS_NAME_PATTERN, DECORATOR, kDataTypeMap } from '../constants.js';
7
+ import { DataType } from '../data-type/data-type.js';
8
+ import { RpcOperationDecoratorFactory } from '../decorators/rpc-operation.decorator.js';
9
+ /**
10
+ * RpcOperation
11
+ */
12
+ export const RpcOperation = function (...args) {
13
+ // Decorator
14
+ if (!this) {
15
+ const [payloadType, options] = args;
16
+ const decoratorChain = [];
17
+ return RpcOperation[DECORATOR].call(undefined, decoratorChain, payloadType, options);
18
+ }
19
+ // Constructor
20
+ const [resource, initArgs] = args;
21
+ DocumentElement.call(this, resource);
22
+ if (!CLASS_NAME_PATTERN.test(initArgs.name))
23
+ throw new TypeError(`Invalid operation name (${initArgs.name})`);
24
+ const _this = asMutable(this);
25
+ _this.headers = [];
26
+ _this.types = _this.node[kDataTypeMap] = new DataTypeMap();
27
+ _this.name = initArgs.name;
28
+ _this.description = initArgs.description;
29
+ _this.channel = initArgs.channel;
30
+ if (initArgs?.payloadType) {
31
+ _this.payloadType =
32
+ initArgs?.payloadType instanceof DataType
33
+ ? initArgs.payloadType
34
+ : _this.owner.node.getDataType(initArgs.payloadType);
35
+ }
36
+ if (initArgs?.keyType) {
37
+ _this.keyType =
38
+ initArgs?.keyType instanceof DataType ? initArgs.keyType : _this.owner.node.getDataType(initArgs.keyType);
39
+ }
40
+ };
41
+ /**
42
+ * @class RpcOperation
43
+ */
44
+ class RpcOperationClass extends DocumentElement {
45
+ findHeader(paramName) {
46
+ const paramNameLower = paramName.toLowerCase();
47
+ let prm;
48
+ for (prm of this.headers) {
49
+ if (typeof prm.name === 'string') {
50
+ prm._nameLower = prm._nameLower || prm.name.toLowerCase();
51
+ if (prm._nameLower === paramNameLower)
52
+ return prm;
53
+ }
54
+ if (prm.name instanceof RegExp && prm.name.test(paramName))
55
+ return prm;
56
+ }
57
+ }
58
+ toJSON() {
59
+ const out = omitUndefined({
60
+ kind: OpraSchema.RpcOperation.Kind,
61
+ description: this.description,
62
+ channel: this.channel,
63
+ payloadType: this.payloadType.name ? this.payloadType.name : this.payloadType.toJSON(),
64
+ keyType: this.keyType ? (this.keyType.name ? this.keyType.name : this.keyType.toJSON()) : undefined,
65
+ response: this.response?.toJSON(),
66
+ });
67
+ if (this.headers.length) {
68
+ out.headers = [];
69
+ for (const prm of this.headers) {
70
+ out.headers.push(prm.toJSON());
71
+ }
72
+ }
73
+ return out;
74
+ }
75
+ }
76
+ RpcOperation.prototype = RpcOperationClass.prototype;
77
+ RpcOperation[DECORATOR] = RpcOperationDecoratorFactory;
@@ -0,0 +1,4 @@
1
+ export * from './http-headers-codes.enum.js';
2
+ export * from './http-status-codes.enum.js';
3
+ export * from './http-status-messages.js';
4
+ export * from './mime-types.enum.js';
@@ -1,4 +1,4 @@
1
- import { HttpStatusCode } from '../../http/index.js';
1
+ import { HttpStatusCode } from '../../enums/index.js';
2
2
  import { translate } from '../../i18n/index.js';
3
3
  import { OpraHttpError } from '../opra-http-error.js';
4
4
  /**
@@ -1,4 +1,4 @@
1
- import { HttpStatusCode } from '../../http/index.js';
1
+ import { HttpStatusCode } from '../../enums/index.js';
2
2
  import { translate } from '../../i18n/index.js';
3
3
  import { OpraHttpError } from '../opra-http-error.js';
4
4
  /**
package/esm/index.js CHANGED
@@ -1,8 +1,8 @@
1
1
  export * from './document/index.js';
2
+ export * from './enums/index.js';
2
3
  export * from './exception/index.js';
3
4
  export * from './filter/index.js';
4
5
  export * from './helpers/index.js';
5
- export * from './http/index.js';
6
6
  export * from './i18n/index.js';
7
7
  export * from './schema/index.js';
8
8
  export * from './types.js';
@@ -16,6 +16,9 @@ export * from './http/http-operation-response.interface.js';
16
16
  export * from './http/http-parameter.interface.js';
17
17
  export * from './http/http-request-body.interface.js';
18
18
  export * from './http/http-status-range.interface.js';
19
+ export * from './rpc/rpc-controller.interface.js';
20
+ export * from './rpc/rpc-header.interface.js';
21
+ export * from './rpc/rpc-operation.interface.js';
19
22
  export * from './type-guards.js';
20
23
  export * from './types.js';
21
24
  export * from './value.interface.js';