@opra/common 1.0.0-beta.2 → 1.0.0-beta.3
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.
- package/browser/index.cjs +5 -5
- package/browser/index.mjs +5 -5
- package/cjs/document/api-document.js +14 -0
- package/cjs/document/common/api-base.js +5 -3
- package/cjs/document/common/document-node.js +6 -2
- package/cjs/document/constants.js +2 -1
- package/cjs/document/decorators/http-controller.decorator.js +1 -1
- package/cjs/document/decorators/http-operation-entity.decorator.js +1 -1
- package/cjs/document/decorators/http-operation.decorator.js +5 -5
- package/cjs/document/decorators/msg-controller.decorator.js +64 -0
- package/cjs/document/decorators/msg-operation.decorator.js +80 -0
- package/cjs/document/factory/api-document.factory.js +9 -3
- package/cjs/document/factory/data-type.factory.js +20 -0
- package/cjs/document/factory/http-api.factory.js +50 -77
- package/cjs/document/factory/msg-api.factory.js +202 -0
- package/cjs/document/http/http-api.js +5 -4
- package/cjs/document/http/http-controller.js +16 -0
- package/cjs/document/index.js +6 -0
- package/cjs/document/msg/msg-api.js +54 -0
- package/cjs/document/msg/msg-controller.js +116 -0
- package/cjs/document/msg/msg-header.js +40 -0
- package/cjs/document/msg/msg-operation-response.js +58 -0
- package/cjs/document/msg/msg-operation.js +80 -0
- package/cjs/enums/index.js +7 -0
- package/cjs/exception/http-errors/forbidden.error.js +1 -1
- package/cjs/exception/http-errors/resource-not.available.error.js +1 -1
- package/cjs/index.js +1 -1
- package/cjs/schema/msg/msg-controller.interface.js +11 -0
- package/cjs/schema/msg/msg-header.interface.js +2 -0
- package/cjs/schema/msg/msg-operation.interface.js +7 -0
- package/cjs/schema/opra-schema.js +3 -0
- package/esm/document/api-document.js +14 -0
- package/esm/document/common/api-base.js +5 -3
- package/esm/document/common/document-node.js +6 -2
- package/esm/document/constants.js +1 -0
- package/esm/document/decorators/http-controller.decorator.js +1 -1
- package/esm/document/decorators/http-operation-entity.decorator.js +1 -1
- package/esm/document/decorators/http-operation.decorator.js +5 -5
- package/esm/document/decorators/msg-controller.decorator.js +60 -0
- package/esm/document/decorators/msg-operation.decorator.js +76 -0
- package/esm/document/factory/api-document.factory.js +9 -3
- package/esm/document/factory/data-type.factory.js +20 -0
- package/esm/document/factory/http-api.factory.js +50 -77
- package/esm/document/factory/msg-api.factory.js +198 -0
- package/esm/document/http/http-api.js +5 -4
- package/esm/document/http/http-controller.js +17 -1
- package/esm/document/index.js +6 -0
- package/esm/document/msg/msg-api.js +50 -0
- package/esm/document/msg/msg-controller.js +113 -0
- package/esm/document/msg/msg-header.js +37 -0
- package/esm/document/msg/msg-operation-response.js +54 -0
- package/esm/document/msg/msg-operation.js +77 -0
- package/esm/enums/index.js +4 -0
- package/esm/exception/http-errors/forbidden.error.js +1 -1
- package/esm/exception/http-errors/resource-not.available.error.js +1 -1
- package/esm/index.js +1 -1
- package/esm/schema/msg/msg-controller.interface.js +8 -0
- package/esm/schema/msg/msg-header.interface.js +1 -0
- package/esm/schema/msg/msg-operation.interface.js +4 -0
- package/esm/schema/opra-schema.js +3 -0
- package/package.json +2 -2
- package/types/document/api-document.d.ts +5 -2
- package/types/document/common/api-base.d.ts +3 -2
- package/types/document/constants.d.ts +1 -0
- package/types/document/decorators/http-operation.decorator.d.ts +3 -3
- package/types/document/decorators/msg-controller.decorator.d.ts +11 -0
- package/types/document/decorators/msg-operation.decorator.d.ts +29 -0
- package/types/document/factory/api-document.factory.d.ts +2 -1
- package/types/document/factory/data-type.factory.d.ts +1 -0
- package/types/document/factory/http-api.factory.d.ts +10 -6
- package/types/document/factory/msg-api.factory.d.ts +40 -0
- package/types/document/http/http-api.d.ts +8 -3
- package/types/document/http/http-controller.d.ts +8 -2
- package/types/document/index.d.ts +8 -0
- package/types/document/msg/msg-api.d.ts +27 -0
- package/types/document/msg/msg-controller.d.ts +89 -0
- package/types/document/msg/msg-header.d.ts +47 -0
- package/types/document/msg/msg-operation-response.d.ts +41 -0
- package/types/document/msg/msg-operation.d.ts +77 -0
- package/types/enums/index.d.ts +4 -0
- package/types/exception/http-errors/forbidden.error.d.ts +1 -1
- package/types/index.d.cts +1 -1
- package/types/index.d.ts +1 -1
- package/types/schema/api-document.interface.d.ts +27 -4
- package/types/schema/msg/msg-controller.interface.d.ts +22 -0
- package/types/schema/msg/msg-header.interface.d.ts +19 -0
- package/types/schema/msg/msg-operation.interface.d.ts +26 -0
- package/types/schema/opra-schema.d.ts +3 -0
- package/cjs/http/index.js +0 -7
- package/esm/http/index.js +0 -4
- package/types/http/index.d.ts +0 -4
- /package/cjs/{http/enums → enums}/http-headers-codes.enum.js +0 -0
- /package/cjs/{http/enums → enums}/http-status-codes.enum.js +0 -0
- /package/cjs/{http/enums → enums}/http-status-messages.js +0 -0
- /package/cjs/{http/enums → enums}/mime-types.enum.js +0 -0
- /package/esm/{http/enums → enums}/http-headers-codes.enum.js +0 -0
- /package/esm/{http/enums → enums}/http-status-codes.enum.js +0 -0
- /package/esm/{http/enums → enums}/http-status-messages.js +0 -0
- /package/esm/{http/enums → enums}/mime-types.enum.js +0 -0
- /package/types/{http/enums → enums}/http-headers-codes.enum.d.ts +0 -0
- /package/types/{http/enums → enums}/http-status-codes.enum.d.ts +0 -0
- /package/types/{http/enums → enums}/http-status-messages.d.ts +0 -0
- /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 { MSG_CONTROLLER_METADATA } from '../constants.js';
|
|
3
|
+
import { MsgApi } from '../msg/msg-api.js';
|
|
4
|
+
import { MsgController } from '../msg/msg-controller.js';
|
|
5
|
+
import { MsgHeader } from '../msg/msg-header.js';
|
|
6
|
+
import { MsgOperation } from '../msg/msg-operation.js';
|
|
7
|
+
import { MsgOperationResponse } from '../msg/msg-operation-response.js';
|
|
8
|
+
import { DataTypeFactory } from './data-type.factory.js';
|
|
9
|
+
/**
|
|
10
|
+
* @class MsgApiFactory
|
|
11
|
+
*/
|
|
12
|
+
export class MsgApiFactory {
|
|
13
|
+
/**
|
|
14
|
+
* Generates MsgApi
|
|
15
|
+
* @param context
|
|
16
|
+
* @param init
|
|
17
|
+
*/
|
|
18
|
+
static async createApi(context, init) {
|
|
19
|
+
const api = new MsgApi(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(MSG_CONTROLLER_METADATA, thunk);
|
|
51
|
+
if (!metadata)
|
|
52
|
+
return context.addError(`Class "${thunk.name}" doesn't have a valid MsgController metadata`);
|
|
53
|
+
ctor = thunk;
|
|
54
|
+
}
|
|
55
|
+
else {
|
|
56
|
+
// If thunk is an instance of a class decorated with MsgController()
|
|
57
|
+
ctor = Object.getPrototypeOf(thunk).constructor;
|
|
58
|
+
metadata = Reflect.getMetadata(MSG_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 MsgController()`);
|
|
72
|
+
name = name || metadata.name;
|
|
73
|
+
if (!name)
|
|
74
|
+
throw new TypeError(`Controller name required`);
|
|
75
|
+
const controller = new MsgController(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 MsgHeader(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 MsgOperation(controller, {
|
|
112
|
+
...operationMeta,
|
|
113
|
+
name: operationName,
|
|
114
|
+
types: undefined,
|
|
115
|
+
payloadType: undefined,
|
|
116
|
+
keyType: undefined,
|
|
117
|
+
});
|
|
118
|
+
await this._initMsgOperation(context, operation, operationMeta);
|
|
119
|
+
controller.operations.set(operation.name, operation);
|
|
120
|
+
});
|
|
121
|
+
}
|
|
122
|
+
});
|
|
123
|
+
}
|
|
124
|
+
return controller;
|
|
125
|
+
}
|
|
126
|
+
/**
|
|
127
|
+
* Initializes MsgOperation
|
|
128
|
+
* @param context
|
|
129
|
+
* @param operation
|
|
130
|
+
* @param metadata
|
|
131
|
+
* @protected
|
|
132
|
+
*/
|
|
133
|
+
static async _initMsgOperation(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 MsgHeader(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 MsgOperationResponse(operation, {
|
|
161
|
+
...metadata.response,
|
|
162
|
+
payloadType: undefined,
|
|
163
|
+
keyType: undefined,
|
|
164
|
+
});
|
|
165
|
+
await this._initMsgOperationResponse(context, response, metadata.response);
|
|
166
|
+
operation.response = response;
|
|
167
|
+
});
|
|
168
|
+
}
|
|
169
|
+
}
|
|
170
|
+
/**
|
|
171
|
+
* Initializes MsgOperationResponse
|
|
172
|
+
* @param context
|
|
173
|
+
* @param response
|
|
174
|
+
* @param metadata
|
|
175
|
+
* @protected
|
|
176
|
+
*/
|
|
177
|
+
static async _initMsgOperationResponse(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 MsgHeader(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(
|
|
9
|
-
super(
|
|
8
|
+
constructor(init) {
|
|
9
|
+
super(init);
|
|
10
10
|
// noinspection JSUnusedGlobalSymbols
|
|
11
11
|
this._controllerReverseMap = new WeakMap();
|
|
12
|
-
this.
|
|
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
|
-
|
|
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
|
+
};
|
package/esm/document/index.js
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import 'reflect-metadata';
|
|
2
|
+
import * as MsgOperationDecorator_ from './decorators/msg-operation.decorator.js';
|
|
2
3
|
import * as DataTypeFactory_ from './factory/data-type.factory.js';
|
|
3
4
|
import * as HttpApiFactory_ from './factory/http-api.factory.js';
|
|
4
5
|
export * from './api-document.js';
|
|
@@ -33,8 +34,13 @@ export * from './http/http-operation-response.js';
|
|
|
33
34
|
export * from './http/http-parameter.js';
|
|
34
35
|
export * from './http/http-request-body.js';
|
|
35
36
|
export * from './http/http-status-range.js';
|
|
37
|
+
export * from './msg/msg-api.js';
|
|
38
|
+
export * from './msg/msg-controller.js';
|
|
39
|
+
export * from './msg/msg-header.js';
|
|
40
|
+
export * from './msg/msg-operation.js';
|
|
36
41
|
export var classes;
|
|
37
42
|
(function (classes) {
|
|
38
43
|
classes.HttpApiFactory = HttpApiFactory_.HttpApiFactory;
|
|
39
44
|
classes.DataTypeFactory = DataTypeFactory_.DataTypeFactory;
|
|
45
|
+
classes.MsgOperationDecoratorFactory = MsgOperationDecorator_.MsgOperationDecoratorFactory;
|
|
40
46
|
})(classes || (classes = {}));
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
import { ResponsiveMap } from '../../helpers/index.js';
|
|
2
|
+
import { ApiBase } from '../common/api-base.js';
|
|
3
|
+
/**
|
|
4
|
+
* @class MsgApi
|
|
5
|
+
*/
|
|
6
|
+
export class MsgApi extends ApiBase {
|
|
7
|
+
constructor(init) {
|
|
8
|
+
super(init);
|
|
9
|
+
// noinspection JSUnusedGlobalSymbols
|
|
10
|
+
this._controllerReverseMap = new WeakMap();
|
|
11
|
+
this.transport = 'msg';
|
|
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, MSG_CONTROLLER_METADATA } from '../constants.js';
|
|
7
|
+
import { MsgControllerDecoratorFactory } from '../decorators/msg-controller.decorator.js';
|
|
8
|
+
import { colorFgMagenta, colorFgYellow, colorReset, nodeInspectCustom } from '../utils/inspect.util.js';
|
|
9
|
+
/**
|
|
10
|
+
* MsgController
|
|
11
|
+
*/
|
|
12
|
+
export const MsgController = function (...args) {
|
|
13
|
+
// ClassDecorator
|
|
14
|
+
if (!this)
|
|
15
|
+
return MsgController[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.MsgController.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 MsgController
|
|
38
|
+
*/
|
|
39
|
+
class MsgControllerClass 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 MsgController) {
|
|
53
|
+
return this.node.parent.element.findHeader(paramName, location);
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
/**
|
|
57
|
+
*
|
|
58
|
+
*/
|
|
59
|
+
toString() {
|
|
60
|
+
return `[MsgController ${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}MsgController${colorFgMagenta + this.name + colorReset}]`;
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
MsgController.prototype = MsgControllerClass.prototype;
|
|
98
|
+
Object.assign(MsgController, MsgControllerDecoratorFactory);
|
|
99
|
+
MsgController[DECORATOR] = MsgControllerDecoratorFactory;
|
|
100
|
+
MsgController.OnInit = function () {
|
|
101
|
+
return (target, propertyKey) => {
|
|
102
|
+
const sourceMetadata = (Reflect.getOwnMetadata(MSG_CONTROLLER_METADATA, target.constructor) || {});
|
|
103
|
+
sourceMetadata.onInit = target[propertyKey];
|
|
104
|
+
Reflect.defineMetadata(MSG_CONTROLLER_METADATA, target.constructor, sourceMetadata);
|
|
105
|
+
};
|
|
106
|
+
};
|
|
107
|
+
MsgController.OnShutdown = function () {
|
|
108
|
+
return (target, propertyKey) => {
|
|
109
|
+
const sourceMetadata = (Reflect.getOwnMetadata(MSG_CONTROLLER_METADATA, target.constructor) || {});
|
|
110
|
+
sourceMetadata.onShutdown = target[propertyKey];
|
|
111
|
+
Reflect.defineMetadata(MSG_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 MsgHeader = 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 MsgHeader
|
|
26
|
+
*/
|
|
27
|
+
class MsgHeaderClass 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
|
+
MsgHeader.prototype = MsgHeaderClass.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 MsgOperationResponse
|
|
6
|
+
*/
|
|
7
|
+
export class MsgOperationResponse 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 { MsgOperationDecoratorFactory } from '../decorators/msg-operation.decorator.js';
|
|
9
|
+
/**
|
|
10
|
+
* MsgOperation
|
|
11
|
+
*/
|
|
12
|
+
export const MsgOperation = function (...args) {
|
|
13
|
+
// Decorator
|
|
14
|
+
if (!this) {
|
|
15
|
+
const [payloadType, options] = args;
|
|
16
|
+
const decoratorChain = [];
|
|
17
|
+
return MsgOperation[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 MsgOperation
|
|
43
|
+
*/
|
|
44
|
+
class MsgOperationClass 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.MsgOperation.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
|
+
MsgOperation.prototype = MsgOperationClass.prototype;
|
|
77
|
+
MsgOperation[DECORATOR] = MsgOperationDecoratorFactory;
|
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';
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -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 './msg/msg-controller.interface.js';
|
|
20
|
+
export * from './msg/msg-header.interface.js';
|
|
21
|
+
export * from './msg/msg-operation.interface.js';
|
|
19
22
|
export * from './type-guards.js';
|
|
20
23
|
export * from './types.js';
|
|
21
24
|
export * from './value.interface.js';
|