@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.
Files changed (103) 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/msg-controller.decorator.js +64 -0
  11. package/cjs/document/decorators/msg-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/msg-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/index.js +6 -0
  19. package/cjs/document/msg/msg-api.js +54 -0
  20. package/cjs/document/msg/msg-controller.js +116 -0
  21. package/cjs/document/msg/msg-header.js +40 -0
  22. package/cjs/document/msg/msg-operation-response.js +58 -0
  23. package/cjs/document/msg/msg-operation.js +80 -0
  24. package/cjs/enums/index.js +7 -0
  25. package/cjs/exception/http-errors/forbidden.error.js +1 -1
  26. package/cjs/exception/http-errors/resource-not.available.error.js +1 -1
  27. package/cjs/index.js +1 -1
  28. package/cjs/schema/msg/msg-controller.interface.js +11 -0
  29. package/cjs/schema/msg/msg-header.interface.js +2 -0
  30. package/cjs/schema/msg/msg-operation.interface.js +7 -0
  31. package/cjs/schema/opra-schema.js +3 -0
  32. package/esm/document/api-document.js +14 -0
  33. package/esm/document/common/api-base.js +5 -3
  34. package/esm/document/common/document-node.js +6 -2
  35. package/esm/document/constants.js +1 -0
  36. package/esm/document/decorators/http-controller.decorator.js +1 -1
  37. package/esm/document/decorators/http-operation-entity.decorator.js +1 -1
  38. package/esm/document/decorators/http-operation.decorator.js +5 -5
  39. package/esm/document/decorators/msg-controller.decorator.js +60 -0
  40. package/esm/document/decorators/msg-operation.decorator.js +76 -0
  41. package/esm/document/factory/api-document.factory.js +9 -3
  42. package/esm/document/factory/data-type.factory.js +20 -0
  43. package/esm/document/factory/http-api.factory.js +50 -77
  44. package/esm/document/factory/msg-api.factory.js +198 -0
  45. package/esm/document/http/http-api.js +5 -4
  46. package/esm/document/http/http-controller.js +17 -1
  47. package/esm/document/index.js +6 -0
  48. package/esm/document/msg/msg-api.js +50 -0
  49. package/esm/document/msg/msg-controller.js +113 -0
  50. package/esm/document/msg/msg-header.js +37 -0
  51. package/esm/document/msg/msg-operation-response.js +54 -0
  52. package/esm/document/msg/msg-operation.js +77 -0
  53. package/esm/enums/index.js +4 -0
  54. package/esm/exception/http-errors/forbidden.error.js +1 -1
  55. package/esm/exception/http-errors/resource-not.available.error.js +1 -1
  56. package/esm/index.js +1 -1
  57. package/esm/schema/msg/msg-controller.interface.js +8 -0
  58. package/esm/schema/msg/msg-header.interface.js +1 -0
  59. package/esm/schema/msg/msg-operation.interface.js +4 -0
  60. package/esm/schema/opra-schema.js +3 -0
  61. package/package.json +2 -2
  62. package/types/document/api-document.d.ts +5 -2
  63. package/types/document/common/api-base.d.ts +3 -2
  64. package/types/document/constants.d.ts +1 -0
  65. package/types/document/decorators/http-operation.decorator.d.ts +3 -3
  66. package/types/document/decorators/msg-controller.decorator.d.ts +11 -0
  67. package/types/document/decorators/msg-operation.decorator.d.ts +29 -0
  68. package/types/document/factory/api-document.factory.d.ts +2 -1
  69. package/types/document/factory/data-type.factory.d.ts +1 -0
  70. package/types/document/factory/http-api.factory.d.ts +10 -6
  71. package/types/document/factory/msg-api.factory.d.ts +40 -0
  72. package/types/document/http/http-api.d.ts +8 -3
  73. package/types/document/http/http-controller.d.ts +8 -2
  74. package/types/document/index.d.ts +8 -0
  75. package/types/document/msg/msg-api.d.ts +27 -0
  76. package/types/document/msg/msg-controller.d.ts +89 -0
  77. package/types/document/msg/msg-header.d.ts +47 -0
  78. package/types/document/msg/msg-operation-response.d.ts +41 -0
  79. package/types/document/msg/msg-operation.d.ts +77 -0
  80. package/types/enums/index.d.ts +4 -0
  81. package/types/exception/http-errors/forbidden.error.d.ts +1 -1
  82. package/types/index.d.cts +1 -1
  83. package/types/index.d.ts +1 -1
  84. package/types/schema/api-document.interface.d.ts +27 -4
  85. package/types/schema/msg/msg-controller.interface.d.ts +22 -0
  86. package/types/schema/msg/msg-header.interface.d.ts +19 -0
  87. package/types/schema/msg/msg-operation.interface.d.ts +26 -0
  88. package/types/schema/opra-schema.d.ts +3 -0
  89. package/cjs/http/index.js +0 -7
  90. package/esm/http/index.js +0 -4
  91. package/types/http/index.d.ts +0 -4
  92. /package/cjs/{http/enums → enums}/http-headers-codes.enum.js +0 -0
  93. /package/cjs/{http/enums → enums}/http-status-codes.enum.js +0 -0
  94. /package/cjs/{http/enums → enums}/http-status-messages.js +0 -0
  95. /package/cjs/{http/enums → enums}/mime-types.enum.js +0 -0
  96. /package/esm/{http/enums → enums}/http-headers-codes.enum.js +0 -0
  97. /package/esm/{http/enums → enums}/http-status-codes.enum.js +0 -0
  98. /package/esm/{http/enums → enums}/http-status-messages.js +0 -0
  99. /package/esm/{http/enums → enums}/mime-types.enum.js +0 -0
  100. /package/types/{http/enums → enums}/http-headers-codes.enum.d.ts +0 -0
  101. /package/types/{http/enums → enums}/http-status-codes.enum.d.ts +0 -0
  102. /package/types/{http/enums → enums}/http-status-messages.d.ts +0 -0
  103. /package/types/{http/enums → enums}/mime-types.enum.d.ts +0 -0
@@ -0,0 +1,11 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.MsgController = void 0;
4
+ /**
5
+ *
6
+ * @namespace MsgController
7
+ */
8
+ var MsgController;
9
+ (function (MsgController) {
10
+ MsgController.Kind = 'MsgController';
11
+ })(MsgController || (exports.MsgController = MsgController = {}));
@@ -0,0 +1,2 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
@@ -0,0 +1,7 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.MsgOperation = void 0;
4
+ var MsgOperation;
5
+ (function (MsgOperation) {
6
+ MsgOperation.Kind = 'MsgOperation';
7
+ })(MsgOperation || (exports.MsgOperation = MsgOperation = {}));
@@ -19,6 +19,9 @@ tslib_1.__exportStar(require("./http/http-operation-response.interface.js"), exp
19
19
  tslib_1.__exportStar(require("./http/http-parameter.interface.js"), exports);
20
20
  tslib_1.__exportStar(require("./http/http-request-body.interface.js"), exports);
21
21
  tslib_1.__exportStar(require("./http/http-status-range.interface.js"), exports);
22
+ tslib_1.__exportStar(require("./msg/msg-controller.interface.js"), exports);
23
+ tslib_1.__exportStar(require("./msg/msg-header.interface.js"), exports);
24
+ tslib_1.__exportStar(require("./msg/msg-operation.interface.js"), exports);
22
25
  tslib_1.__exportStar(require("./type-guards.js"), exports);
23
26
  tslib_1.__exportStar(require("./types.js"), exports);
24
27
  tslib_1.__exportStar(require("./value.interface.js"), exports);
@@ -6,6 +6,8 @@ import { DataTypeMap } from './common/data-type-map.js';
6
6
  import { DocumentElement } from './common/document-element.js';
7
7
  import { BUILTIN, kDataTypeMap, kTypeNSMap, NAMESPACE_PATTERN } from './constants.js';
8
8
  import { DataType } from './data-type/data-type.js';
9
+ import { HttpApi } from './http/http-api.js';
10
+ import { MsgApi } from './msg/msg-api.js';
9
11
  /**
10
12
  *
11
13
  * @class ApiDocument
@@ -41,6 +43,18 @@ export class ApiDocument extends DocumentElement {
41
43
  return d;
42
44
  }
43
45
  }
46
+ get httpApi() {
47
+ if (!(this.api && this.api instanceof HttpApi)) {
48
+ throw new TypeError('The document do not contains HttpApi instance');
49
+ }
50
+ return this.api;
51
+ }
52
+ get msgApi() {
53
+ if (!(this.api && this.api instanceof MsgApi)) {
54
+ throw new TypeError('The document do not contains MsgApi instance');
55
+ }
56
+ return this.api;
57
+ }
44
58
  toJSON() {
45
59
  return this.export();
46
60
  }
@@ -2,13 +2,15 @@ import { omitUndefined } from '../../helpers/index.js';
2
2
  import { CLASS_NAME_PATTERN } from '../constants.js';
3
3
  import { DocumentElement } from './document-element.js';
4
4
  export class ApiBase extends DocumentElement {
5
- constructor(owner) {
6
- super(owner);
5
+ constructor(init) {
6
+ super(init.owner);
7
7
  this.name = 'OpraApi';
8
+ this.name = init.name;
9
+ this.description = init.description;
8
10
  }
9
11
  toJSON() {
10
12
  return omitUndefined({
11
- protocol: this.protocol,
13
+ transport: this.transport,
12
14
  name: this.name,
13
15
  description: this.description,
14
16
  });
@@ -47,8 +47,12 @@ export class DocumentNode {
47
47
  const metadata = nameOrCtor[DATATYPE_METADATA];
48
48
  name = metadata?.name;
49
49
  }
50
- if (typeof nameOrCtor === 'string')
51
- name = nameOrCtor;
50
+ if (!name) {
51
+ if (nameOrCtor && typeof nameOrCtor === 'string')
52
+ name = nameOrCtor;
53
+ else if (typeof nameOrCtor === 'function')
54
+ name = nameOrCtor.name;
55
+ }
52
56
  throw new TypeError(`Unknown data type` + (name ? ' (' + name + ')' : ''));
53
57
  }
54
58
  getDataTypeNameWithNs(dataType) {
@@ -1,5 +1,6 @@
1
1
  export const DATATYPE_METADATA = Symbol.for('opra.type.metadata');
2
2
  export const HTTP_CONTROLLER_METADATA = Symbol('opra.http-controller.metadata');
3
+ export const MSG_CONTROLLER_METADATA = Symbol('opra.msg-controller.metadata');
3
4
  export const DECODER = Symbol.for('opra.type.decoder');
4
5
  export const ENCODER = Symbol('opra.type.encoder');
5
6
  export const DECORATOR = Symbol.for('DECORATOR');
@@ -27,7 +27,7 @@ export function HttpControllerDecoratorFactory(options) {
27
27
  }, { deep: true });
28
28
  Reflect.defineMetadata(HTTP_CONTROLLER_METADATA, metadata, target);
29
29
  for (const fn of decoratorChain)
30
- fn(metadata);
30
+ fn(metadata, target);
31
31
  Reflect.defineMetadata(HTTP_CONTROLLER_METADATA, metadata, target);
32
32
  };
33
33
  /**
@@ -1,5 +1,5 @@
1
+ import { HttpStatusCode, MimeTypes } from '../../enums/index.js';
1
2
  import { FilterRules } from '../../filter/filter-rules.js';
2
- import { HttpStatusCode, MimeTypes } from '../../http/index.js';
3
3
  import { DATATYPE_METADATA } from '../constants.js';
4
4
  import { FieldPathType, FilterType } from '../data-type/extended-types/index.js';
5
5
  import { IntegerType } from '../data-type/primitive-types/index.js';
@@ -1,5 +1,5 @@
1
1
  import omit from 'lodash.omit';
2
- import { MimeTypes } from '../../http/index.js';
2
+ import { MimeTypes } from '../../enums/index.js';
3
3
  import { OpraSchema } from '../../schema/index.js';
4
4
  import { HTTP_CONTROLLER_METADATA } from '../constants.js';
5
5
  export function HttpOperationDecoratorFactory(decoratorChain, options) {
@@ -13,13 +13,13 @@ export function HttpOperationDecoratorFactory(decoratorChain, options) {
13
13
  kind: OpraSchema.HttpOperation.Kind,
14
14
  ...omit(options, ['kind']),
15
15
  };
16
- const resourceMetadata = (Reflect.getOwnMetadata(HTTP_CONTROLLER_METADATA, target.constructor) ||
16
+ const controllerMetadata = (Reflect.getOwnMetadata(HTTP_CONTROLLER_METADATA, target.constructor) ||
17
17
  {});
18
- resourceMetadata.operations = resourceMetadata.operations || {};
19
- resourceMetadata.operations[propertyKey] = operationMetadata;
18
+ controllerMetadata.operations = controllerMetadata.operations || {};
19
+ controllerMetadata.operations[propertyKey] = operationMetadata;
20
20
  for (const fn of decoratorChain)
21
21
  fn(operationMetadata);
22
- Reflect.defineMetadata(HTTP_CONTROLLER_METADATA, resourceMetadata, target.constructor);
22
+ Reflect.defineMetadata(HTTP_CONTROLLER_METADATA, controllerMetadata, target.constructor);
23
23
  });
24
24
  /**
25
25
  *
@@ -0,0 +1,60 @@
1
+ import omit from 'lodash.omit';
2
+ import merge from 'putil-merge';
3
+ import { OpraSchema } from '../../schema/index.js';
4
+ import { MSG_CONTROLLER_METADATA } from '../constants.js';
5
+ const CLASS_NAME_PATTERN = /^(.*)(Controller)$/;
6
+ export function MsgControllerDecoratorFactory(options) {
7
+ const decoratorChain = [];
8
+ /**
9
+ *
10
+ */
11
+ const decorator = function (target) {
12
+ let name = options?.name;
13
+ if (!name)
14
+ name = CLASS_NAME_PATTERN.exec(target.name)?.[1] || target.name;
15
+ const metadata = {};
16
+ const baseMetadata = Reflect.getOwnMetadata(MSG_CONTROLLER_METADATA, Object.getPrototypeOf(target));
17
+ if (baseMetadata)
18
+ merge(metadata, baseMetadata, { deep: true });
19
+ const oldMetadata = Reflect.getOwnMetadata(MSG_CONTROLLER_METADATA, target);
20
+ if (oldMetadata)
21
+ merge(metadata, oldMetadata, { deep: true });
22
+ merge(metadata, {
23
+ kind: OpraSchema.MsgController.Kind,
24
+ name,
25
+ path: name,
26
+ ...omit(options, ['kind', 'name', 'instance', 'endpoints', 'key']),
27
+ }, { deep: true });
28
+ Reflect.defineMetadata(MSG_CONTROLLER_METADATA, metadata, target);
29
+ for (const fn of decoratorChain)
30
+ fn(metadata);
31
+ Reflect.defineMetadata(MSG_CONTROLLER_METADATA, metadata, target);
32
+ };
33
+ /**
34
+ *
35
+ */
36
+ decorator.Header = (name, arg1) => {
37
+ decoratorChain.push((meta) => {
38
+ const paramMeta = typeof arg1 === 'string' || typeof arg1 === 'function'
39
+ ? {
40
+ name,
41
+ type: arg1,
42
+ }
43
+ : { ...arg1, name };
44
+ meta.headers = meta.headers || [];
45
+ meta.headers.push(paramMeta);
46
+ });
47
+ return decorator;
48
+ };
49
+ /**
50
+ *
51
+ */
52
+ decorator.UseType = (...type) => {
53
+ decoratorChain.push((meta) => {
54
+ meta.types = meta.types || [];
55
+ meta.types.push(...type);
56
+ });
57
+ return decorator;
58
+ };
59
+ return decorator;
60
+ }
@@ -0,0 +1,76 @@
1
+ import omit from 'lodash.omit';
2
+ import { OpraSchema } from '../../schema/index.js';
3
+ import { MSG_CONTROLLER_METADATA } from '../constants.js';
4
+ const augmentationRegistry = [];
5
+ export function MsgOperationDecoratorFactory(decoratorChain, payloadType, options) {
6
+ let inResponse = false;
7
+ /**
8
+ *
9
+ */
10
+ const decorator = ((target, propertyKey) => {
11
+ if (typeof propertyKey !== 'string')
12
+ throw new TypeError(`Symbol properties can not be decorated`);
13
+ const operationMetadata = {
14
+ kind: OpraSchema.MsgOperation.Kind,
15
+ channel: propertyKey,
16
+ ...omit(options, ['kind']),
17
+ payloadType,
18
+ };
19
+ const controllerMetadata = (Reflect.getOwnMetadata(MSG_CONTROLLER_METADATA, target.constructor) ||
20
+ {});
21
+ controllerMetadata.operations = controllerMetadata.operations || {};
22
+ controllerMetadata.operations[propertyKey] = operationMetadata;
23
+ for (const fn of decoratorChain)
24
+ fn(operationMetadata, target, propertyKey);
25
+ Reflect.defineMetadata(MSG_CONTROLLER_METADATA, controllerMetadata, target.constructor);
26
+ });
27
+ /**
28
+ *
29
+ */
30
+ decorator.UseType = (...type) => {
31
+ decoratorChain.push((meta) => {
32
+ meta.types = meta.types || [];
33
+ meta.types.push(...type);
34
+ });
35
+ return decorator;
36
+ };
37
+ /**
38
+ *
39
+ */
40
+ decorator.Header = (name, arg1) => {
41
+ decoratorChain.push((meta) => {
42
+ const headerMetadata = typeof arg1 === 'string' || typeof arg1 === 'function'
43
+ ? {
44
+ name,
45
+ type: arg1,
46
+ }
47
+ : { ...arg1, name };
48
+ const subMeta = inResponse ? meta.response : meta;
49
+ if (subMeta.headers) {
50
+ subMeta.headers = subMeta.headers.filter(p => String(p.name) !== String(name));
51
+ }
52
+ else
53
+ subMeta.headers = [];
54
+ subMeta.headers.push(headerMetadata);
55
+ });
56
+ return decorator;
57
+ };
58
+ /**
59
+ *
60
+ */
61
+ decorator.Response = (_payloadType, _options) => {
62
+ decoratorChain.push((meta) => {
63
+ inResponse = true;
64
+ meta.response = {
65
+ ..._options,
66
+ payloadType: _payloadType,
67
+ };
68
+ });
69
+ return decorator;
70
+ };
71
+ augmentationRegistry.forEach(fn => fn(decorator, decoratorChain, payloadType, options));
72
+ return decorator;
73
+ }
74
+ MsgOperationDecoratorFactory.augment = function (fn) {
75
+ augmentationRegistry.push(fn);
76
+ };
@@ -8,6 +8,7 @@ import { Base64Type, DateStringType, DateTimeStringType, DateTimeType, DateType,
8
8
  import { AnyType, BigintType, BooleanType, IntegerType, NullType, NumberType, ObjectType, StringType, } from '../data-type/primitive-types/index.js';
9
9
  import { DataTypeFactory } from './data-type.factory.js';
10
10
  import { HttpApiFactory } from './http-api.factory.js';
11
+ import { MsgApiFactory } from './msg-api.factory.js';
11
12
  const OPRA_SPEC_URL = 'https://oprajs.com/spec/v' + OpraSchema.SpecVersion;
12
13
  /**
13
14
  * @class ApiDocumentFactory
@@ -108,13 +109,18 @@ export class ApiDocumentFactory {
108
109
  }
109
110
  if (init.api) {
110
111
  await context.enterAsync(`.api`, async () => {
111
- if (init.api.protocol === 'http') {
112
- const api = await HttpApiFactory.createApi(context, document, init.api);
112
+ if (init.api && init.api.transport === 'http') {
113
+ const api = await HttpApiFactory.createApi(context, { ...init.api, owner: document });
114
+ if (api)
115
+ document.api = api;
116
+ }
117
+ else if (init.api && init.api.transport === 'msg') {
118
+ const api = await MsgApiFactory.createApi(context, { ...init.api, owner: document });
113
119
  if (api)
114
120
  document.api = api;
115
121
  }
116
122
  else
117
- context.addError(`Unknown service protocol (${init.api.protocol})`);
123
+ context.addError(`Unknown service transport (${init.api.transport})`);
118
124
  });
119
125
  }
120
126
  document.invalidate();
@@ -24,6 +24,26 @@ export class DataTypeFactory {
24
24
  return this._createDataType(context, owner, initArgs);
25
25
  }
26
26
  }
27
+ static async resolveDataType(context, owner, v) {
28
+ if (v) {
29
+ const dt = owner.node.findDataType(v);
30
+ if (dt)
31
+ return dt;
32
+ }
33
+ if (typeof v === 'object' || typeof v === 'function') {
34
+ const dt = await DataTypeFactory.createDataType(context, owner, v);
35
+ if (dt)
36
+ return dt;
37
+ }
38
+ if (v) {
39
+ /** To throw not found error */
40
+ const dt = owner.node.getDataType(v);
41
+ /** istanbul ignore next */
42
+ if (dt)
43
+ return dt;
44
+ }
45
+ return owner.node.getDataType('any');
46
+ }
27
47
  /**
28
48
  *
29
49
  * @param context
@@ -16,35 +16,56 @@ export class HttpApiFactory {
16
16
  /**
17
17
  * Generates HttpApi
18
18
  * @param context
19
- * @param document
20
19
  * @param init
21
20
  */
22
- static async createApi(context, document, init) {
23
- const api = new HttpApi(document);
24
- api.name = init.name;
25
- api.description = init.description;
26
- api.url = init.url;
21
+ static async createApi(context, init) {
22
+ const api = new HttpApi(init);
27
23
  if (init.controllers) {
28
24
  await context.enterAsync('.controllers', async () => {
29
- if (Array.isArray(init.controllers)) {
30
- for (const c of init.controllers) {
31
- const controller = await this._createController(context, api, c);
32
- if (controller)
33
- api.controllers.set(controller.name, controller);
34
- }
35
- }
36
- else {
37
- for (const [k, v] of Object.entries(init.controllers)) {
38
- const controller = await this._createController(context, api, v, k);
39
- if (controller)
40
- api.controllers.set(controller.name, controller);
25
+ await this._createControllers(context, api, init.controllers);
26
+ });
27
+ }
28
+ return api;
29
+ }
30
+ static async _createControllers(context, parent, controllers) {
31
+ if (Array.isArray(controllers)) {
32
+ let i = 0;
33
+ for (const c of controllers) {
34
+ let r;
35
+ await context.enterAsync(`[${i++}]`, async () => {
36
+ r = await this._resolveControllerMetadata(context, parent, c);
37
+ });
38
+ if (!r)
39
+ continue;
40
+ await context.enterAsync(`[${r.metadata.name}]`, async () => {
41
+ const controller = await this._createController(context, parent, r.metadata, r.instance, r.ctor);
42
+ if (controller) {
43
+ if (parent.controllers.get(controller.name))
44
+ context.addError(`Duplicate controller name (${r.name})`);
45
+ parent.controllers.set(controller.name, controller);
41
46
  }
47
+ });
48
+ }
49
+ return;
50
+ }
51
+ for (const [k, c] of Object.entries(controllers)) {
52
+ await context.enterAsync(`[${k}]`, async () => {
53
+ const r = await this._resolveControllerMetadata(context, parent, c);
54
+ if (!r)
55
+ return;
56
+ const controller = await this._createController(context, parent, {
57
+ ...r.metadata,
58
+ name: k,
59
+ }, r.instance, r.ctor);
60
+ if (controller) {
61
+ if (parent.controllers.get(controller.name))
62
+ context.addError(`Duplicate controller name (${k})`);
63
+ parent.controllers.set(controller.name, controller);
42
64
  }
43
65
  });
44
66
  }
45
- return api;
46
67
  }
47
- static async _createController(context, parent, thunk, name) {
68
+ static async _resolveControllerMetadata(context, parent, thunk) {
48
69
  if (typeof thunk === 'function' && !isConstructor(thunk)) {
49
70
  thunk = parent instanceof HttpController ? thunk(parent.instance) : thunk();
50
71
  }
@@ -76,12 +97,13 @@ export class HttpApiFactory {
76
97
  }
77
98
  if (!metadata)
78
99
  return context.addError(`Class "${ctor.name}" is not decorated with HttpController()`);
79
- name = name || metadata.name;
80
- if (!name)
100
+ return { metadata, instance, ctor };
101
+ }
102
+ static async _createController(context, parent, metadata, instance, ctor) {
103
+ if (!metadata.name)
81
104
  throw new TypeError(`Controller name required`);
82
105
  const controller = new HttpController(parent, {
83
106
  ...metadata,
84
- name,
85
107
  instance,
86
108
  ctor,
87
109
  });
@@ -97,13 +119,7 @@ export class HttpApiFactory {
97
119
  await context.enterAsync(`[${i++}]`, async () => {
98
120
  const prmArgs = { ...v };
99
121
  await context.enterAsync('.type', async () => {
100
- if (v.type)
101
- prmArgs.type = controller.node.findDataType(v.type);
102
- if (!prmArgs.type && typeof v.type === 'object') {
103
- prmArgs.type = await DataTypeFactory.createDataType(context, controller, v.type);
104
- }
105
- if (!prmArgs.type)
106
- prmArgs.type = controller.node.getDataType('any');
122
+ prmArgs.type = await DataTypeFactory.resolveDataType(context, controller, v.type);
107
123
  });
108
124
  const prm = new HttpParameter(controller, prmArgs);
109
125
  controller.parameters.push(prm);
@@ -124,32 +140,7 @@ export class HttpApiFactory {
124
140
  }
125
141
  if (metadata.controllers) {
126
142
  await context.enterAsync('.controllers', async () => {
127
- if (Array.isArray(metadata.controllers)) {
128
- let k = 0;
129
- for (const v of metadata.controllers) {
130
- await context.enterAsync(`[${k}]`, async () => {
131
- const r = await this._createController(context, controller, v);
132
- if (r) {
133
- if (controller.controllers.get(r.name))
134
- context.addError(`Duplicate controller name (${r.name})`);
135
- controller.controllers.set(r.name, r);
136
- }
137
- });
138
- k++;
139
- }
140
- }
141
- else {
142
- for (const [k, v] of Object.entries(metadata.controllers)) {
143
- await context.enterAsync(`[${k}]`, async () => {
144
- const r = await this._createController(context, controller, v, k);
145
- if (r) {
146
- if (controller.controllers.get(r.name))
147
- context.addError(`Duplicate controller name (${r.name})`);
148
- controller.controllers.set(r.name, r);
149
- }
150
- });
151
- }
152
- }
143
+ await this._createControllers(context, controller, metadata.controllers);
153
144
  });
154
145
  }
155
146
  return controller;
@@ -180,13 +171,7 @@ export class HttpApiFactory {
180
171
  await context.enterAsync(`[${i++}]`, async () => {
181
172
  const prmArgs = { ...v };
182
173
  await context.enterAsync('.type', async () => {
183
- if (v.type)
184
- prmArgs.type = operation.node.findDataType(v.type);
185
- if (!prmArgs.type && typeof v.type === 'object') {
186
- prmArgs.type = await DataTypeFactory.createDataType(context, operation, v.type);
187
- }
188
- if (!prmArgs.type)
189
- prmArgs.type = operation.node.getDataType('any');
174
+ prmArgs.type = await DataTypeFactory.resolveDataType(context, operation, v.type);
190
175
  });
191
176
  const prm = new HttpParameter(operation, prmArgs);
192
177
  operation.parameters.push(prm);
@@ -230,13 +215,7 @@ export class HttpApiFactory {
230
215
  });
231
216
  if (metadata.type) {
232
217
  await context.enterAsync('.type', async () => {
233
- if (metadata.type)
234
- target.type = target.node.findDataType(metadata.type);
235
- if (!target.type && (typeof metadata.type === 'object' || typeof metadata.type === 'function')) {
236
- target.type = await DataTypeFactory.createDataType(context, target, metadata.type);
237
- }
238
- if (!target.type)
239
- target.type = target.node.getDataType('any');
218
+ target.type = await DataTypeFactory.resolveDataType(context, target, metadata.type);
240
219
  });
241
220
  }
242
221
  if (metadata.multipartFields) {
@@ -269,13 +248,7 @@ export class HttpApiFactory {
269
248
  await context.enterAsync(`[${i++}]`, async () => {
270
249
  const prmArgs = { ...v };
271
250
  await context.enterAsync('.type', async () => {
272
- if (v.type)
273
- prmArgs.type = target.node.findDataType(v.type);
274
- if (!prmArgs.type && typeof v.type === 'object') {
275
- prmArgs.type = await DataTypeFactory.createDataType(context, target, v.type);
276
- }
277
- if (!prmArgs.type)
278
- prmArgs.type = target.node.getDataType('any');
251
+ prmArgs.type = await DataTypeFactory.resolveDataType(context, target, v.type);
279
252
  });
280
253
  const prm = new HttpParameter(target, prmArgs);
281
254
  target.parameters.push(prm);