@opra/common 1.19.7 → 1.20.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 (100) hide show
  1. package/browser/index.cjs +5 -5
  2. package/browser/index.mjs +5 -5
  3. package/cjs/document/api-document.js +14 -2
  4. package/cjs/document/common/document-node.js +12 -1
  5. package/cjs/document/constants.js +2 -1
  6. package/cjs/document/data-type/api-field.js +7 -6
  7. package/cjs/document/data-type/array-type.js +78 -0
  8. package/cjs/document/data-type/complex-type-base.js +3 -4
  9. package/cjs/document/data-type/extended-types/base64.type.js +6 -1
  10. package/cjs/document/data-type/extended-types/date-time.type.js +1 -1
  11. package/cjs/document/data-type/extended-types/date.type.js +1 -1
  12. package/cjs/document/data-type/extended-types/field-path.type.js +3 -3
  13. package/cjs/document/data-type/extended-types/filter.type.js +1 -1
  14. package/cjs/document/data-type/simple-type.js +10 -2
  15. package/cjs/document/decorators/http-operation.decorator.js +13 -0
  16. package/cjs/document/decorators/mq-operation.decorator.js +12 -8
  17. package/cjs/document/decorators/ws-controller.decorator.js +4 -4
  18. package/cjs/document/decorators/ws-operation.decorator.js +6 -7
  19. package/cjs/document/decorators/ws-param.decorator.js +22 -0
  20. package/cjs/document/factory/api-document.factory.js +9 -0
  21. package/cjs/document/factory/data-type.factory.js +27 -0
  22. package/cjs/document/factory/mq-api.factory.js +4 -4
  23. package/cjs/document/factory/ws-api.factory.js +26 -4
  24. package/cjs/document/http/http-media-type.js +13 -4
  25. package/cjs/document/http/http-parameter.js +8 -0
  26. package/cjs/document/index.js +2 -0
  27. package/cjs/document/mq/mq-header.js +8 -0
  28. package/cjs/document/mq/mq-operation-response.js +9 -9
  29. package/cjs/document/mq/mq-operation.js +23 -10
  30. package/cjs/document/ws/ws-operation.js +22 -20
  31. package/cjs/filter/filter-rules.js +2 -2
  32. package/cjs/schema/data-type/array-type.interface.js +7 -0
  33. package/cjs/schema/opra-schema.js +1 -0
  34. package/cjs/schema/type-guards.js +7 -1
  35. package/esm/document/api-document.js +14 -2
  36. package/esm/document/common/document-node.js +12 -1
  37. package/esm/document/constants.js +1 -0
  38. package/esm/document/data-type/api-field.js +7 -6
  39. package/esm/document/data-type/array-type.js +75 -0
  40. package/esm/document/data-type/complex-type-base.js +3 -4
  41. package/esm/document/data-type/extended-types/base64.type.js +6 -1
  42. package/esm/document/data-type/extended-types/date-time.type.js +1 -1
  43. package/esm/document/data-type/extended-types/date.type.js +1 -1
  44. package/esm/document/data-type/extended-types/field-path.type.js +3 -3
  45. package/esm/document/data-type/extended-types/filter.type.js +1 -1
  46. package/esm/document/data-type/simple-type.js +10 -2
  47. package/esm/document/decorators/http-operation.decorator.js +13 -0
  48. package/esm/document/decorators/mq-operation.decorator.js +13 -9
  49. package/esm/document/decorators/ws-controller.decorator.js +5 -5
  50. package/esm/document/decorators/ws-operation.decorator.js +7 -8
  51. package/esm/document/decorators/ws-param.decorator.js +19 -0
  52. package/esm/document/factory/api-document.factory.js +9 -0
  53. package/esm/document/factory/data-type.factory.js +27 -0
  54. package/esm/document/factory/mq-api.factory.js +4 -4
  55. package/esm/document/factory/ws-api.factory.js +27 -5
  56. package/esm/document/http/http-media-type.js +13 -4
  57. package/esm/document/http/http-parameter.js +8 -0
  58. package/esm/document/index.js +2 -0
  59. package/esm/document/mq/mq-header.js +8 -0
  60. package/esm/document/mq/mq-operation-response.js +9 -9
  61. package/esm/document/mq/mq-operation.js +23 -10
  62. package/esm/document/ws/ws-operation.js +22 -20
  63. package/esm/filter/filter-rules.js +2 -2
  64. package/esm/schema/data-type/array-type.interface.js +4 -0
  65. package/esm/schema/opra-schema.js +1 -0
  66. package/esm/schema/type-guards.js +6 -1
  67. package/package.json +1 -1
  68. package/types/document/api-document.d.ts +6 -3
  69. package/types/document/common/document-node.d.ts +7 -0
  70. package/types/document/constants.d.ts +1 -0
  71. package/types/document/data-type/api-field.d.ts +6 -9
  72. package/types/document/data-type/array-type.d.ts +76 -0
  73. package/types/document/data-type/extended-types/base64.type.d.ts +2 -1
  74. package/types/document/data-type/extended-types/date-time.type.d.ts +2 -1
  75. package/types/document/data-type/extended-types/date.type.d.ts +2 -1
  76. package/types/document/data-type/extended-types/field-path.type.d.ts +5 -2
  77. package/types/document/data-type/extended-types/filter.type.d.ts +3 -1
  78. package/types/document/data-type/simple-type.d.ts +6 -2
  79. package/types/document/decorators/mq-operation.decorator.d.ts +5 -5
  80. package/types/document/decorators/ws-controller.decorator.d.ts +0 -2
  81. package/types/document/decorators/ws-operation.decorator.d.ts +5 -5
  82. package/types/document/decorators/ws-param.decorator.d.ts +2 -0
  83. package/types/document/factory/data-type.factory.d.ts +12 -2
  84. package/types/document/http/http-media-type.d.ts +3 -1
  85. package/types/document/http/http-parameter.d.ts +5 -1
  86. package/types/document/index.d.ts +2 -0
  87. package/types/document/mq/mq-header.d.ts +5 -1
  88. package/types/document/mq/mq-operation-response.d.ts +8 -4
  89. package/types/document/mq/mq-operation.d.ts +13 -6
  90. package/types/document/ws/ws-controller.d.ts +0 -1
  91. package/types/document/ws/ws-operation.d.ts +14 -14
  92. package/types/schema/data-type/array-type.interface.d.ts +16 -0
  93. package/types/schema/data-type/data-type.interface.d.ts +3 -2
  94. package/types/schema/data-type/field.interface.d.ts +1 -0
  95. package/types/schema/http/http-media-type.interface.d.ts +1 -0
  96. package/types/schema/mq/mq-operation.interface.d.ts +2 -2
  97. package/types/schema/opra-schema.d.ts +1 -0
  98. package/types/schema/type-guards.d.ts +2 -0
  99. package/types/schema/value.interface.d.ts +1 -0
  100. package/types/schema/ws/ws-operation.interface.d.ts +3 -2
@@ -18,7 +18,7 @@ let DateType = class DateType {
18
18
  }
19
19
  [DECODER](properties) {
20
20
  let fn;
21
- if (properties.convertToNative) {
21
+ if (properties.designType === Date) {
22
22
  fn = _isDate;
23
23
  }
24
24
  else {
@@ -8,7 +8,7 @@ let FieldPathType = class FieldPathType {
8
8
  if (attributes)
9
9
  Object.assign(this, attributes);
10
10
  }
11
- [DECODER](properties, element, scope) {
11
+ [DECODER](properties, { element, scope, }) {
12
12
  const dataType = properties.dataType
13
13
  ? element.node.getComplexType(properties.dataType)
14
14
  : element.node.getComplexType('object');
@@ -16,8 +16,8 @@ let FieldPathType = class FieldPathType {
16
16
  const decodeFieldPath = validator('decodeFieldPath', (input) => dataType.normalizeFieldPath(input, { allowSigns, scope }));
17
17
  return vg.pipe([toString, decodeFieldPath]);
18
18
  }
19
- [ENCODER](properties, element, scope) {
20
- return this[DECODER](properties, element, scope);
19
+ [ENCODER](properties, args) {
20
+ return this[DECODER](properties, args);
21
21
  }
22
22
  toJSON(properties, element, options) {
23
23
  const dataType = properties.dataType
@@ -10,7 +10,7 @@ let FilterType = class FilterType {
10
10
  if (attributes)
11
11
  Object.assign(this, attributes);
12
12
  }
13
- [DECODER](properties, element) {
13
+ [DECODER](properties, { element }) {
14
14
  const dataType = properties.dataType
15
15
  ? element.node.getComplexType(properties.dataType)
16
16
  : element.node.getComplexType('object');
@@ -71,7 +71,11 @@ class SimpleTypeClass extends DataType {
71
71
  let t = this;
72
72
  while (t) {
73
73
  if (t._generateDecoder)
74
- return t._generateDecoder(prop, options?.documentElement || this.owner, options?.scope);
74
+ return t._generateDecoder(prop, {
75
+ dataType: this,
76
+ element: options?.documentElement || this.owner,
77
+ scope: options?.scope,
78
+ });
75
79
  t = this.base;
76
80
  }
77
81
  return isAny;
@@ -79,7 +83,11 @@ class SimpleTypeClass extends DataType {
79
83
  let t = this;
80
84
  while (t) {
81
85
  if (t._generateEncoder)
82
- return t._generateEncoder(prop, options?.documentElement || this.owner, options?.scope);
86
+ return t._generateEncoder(prop, {
87
+ dataType: this,
88
+ element: options?.documentElement || this.owner,
89
+ scope: options?.scope,
90
+ });
83
91
  t = this.base;
84
92
  }
85
93
  return isAny;
@@ -1,3 +1,4 @@
1
+ import { isConstructor } from '@jsopen/objects';
1
2
  import { MimeTypes } from '../../enums/index.js';
2
3
  import { OpraSchema } from '../../schema/index.js';
3
4
  import { HTTP_CONTROLLER_METADATA } from '../constants.js';
@@ -31,6 +32,8 @@ export function HttpOperationDecoratorFactory(decoratorChain, options) {
31
32
  type: arg1,
32
33
  }
33
34
  : { ...arg1, name, location: 'cookie' };
35
+ if (isConstructor(paramMeta.type))
36
+ paramMeta.designType = paramMeta.type;
34
37
  if (meta.parameters) {
35
38
  meta.parameters = meta.parameters.filter(p => !(p.location === 'cookie' && String(p.name) === String(name)));
36
39
  }
@@ -52,6 +55,8 @@ export function HttpOperationDecoratorFactory(decoratorChain, options) {
52
55
  type: arg1,
53
56
  }
54
57
  : { ...arg1, name, location: 'header' };
58
+ if (isConstructor(paramMeta.type))
59
+ paramMeta.designType = paramMeta.type;
55
60
  if (meta.parameters) {
56
61
  meta.parameters = meta.parameters.filter(p => !(p.location === 'header' && String(p.name) === String(name)));
57
62
  }
@@ -73,6 +78,8 @@ export function HttpOperationDecoratorFactory(decoratorChain, options) {
73
78
  type: arg1,
74
79
  }
75
80
  : { ...arg1, name, location: 'query' };
81
+ if (isConstructor(paramMeta.type))
82
+ paramMeta.designType = paramMeta.type;
76
83
  if (meta.parameters) {
77
84
  meta.parameters = meta.parameters.filter(p => !(p.location === 'query' && String(p.name) === String(name)));
78
85
  }
@@ -94,6 +101,8 @@ export function HttpOperationDecoratorFactory(decoratorChain, options) {
94
101
  type: arg1,
95
102
  }
96
103
  : { ...arg1, name, location: 'path' };
104
+ if (isConstructor(paramMeta.type))
105
+ paramMeta.designType = paramMeta.type;
97
106
  if (meta.parameters) {
98
107
  meta.parameters = meta.parameters.filter(p => !(p.location === 'path' && String(p.name) === String(name)));
99
108
  }
@@ -119,6 +128,8 @@ export function HttpOperationDecoratorFactory(decoratorChain, options) {
119
128
  if (responseMeta.contentType === MimeTypes.opra_response_json) {
120
129
  responseMeta.contentEncoding = responseMeta.contentEncoding || 'utf-8';
121
130
  }
131
+ if (isConstructor(responseMeta.type))
132
+ responseMeta.designType = responseMeta.type;
122
133
  decoratorChain.push((meta) => {
123
134
  meta.responses = meta.responses || [];
124
135
  meta.responses.push(responseMeta);
@@ -130,6 +141,8 @@ export function HttpOperationDecoratorFactory(decoratorChain, options) {
130
141
  if (contentMeta.type) {
131
142
  contentMeta.contentType = contentMeta.contentType || MimeTypes.json;
132
143
  contentMeta.contentEncoding = contentMeta.contentEncoding || 'utf-8';
144
+ if (isConstructor(contentMeta.type))
145
+ contentMeta.designType = contentMeta.type;
133
146
  }
134
147
  decoratorChain.push((operationMetadata) => {
135
148
  operationMetadata.requestBody = operationMetadata.requestBody || {
@@ -1,8 +1,8 @@
1
- import { omit } from '@jsopen/objects';
1
+ import { isConstructor, omit } from '@jsopen/objects';
2
2
  import { OpraSchema } from '../../schema/index.js';
3
3
  import { MQ_CONTROLLER_METADATA } from '../constants.js';
4
4
  const augmentationRegistry = [];
5
- export function MQOperationDecoratorFactory(decoratorChain, payloadType, options) {
5
+ export function MQOperationDecoratorFactory(decoratorChain, type, options) {
6
6
  let inResponse = false;
7
7
  /**
8
8
  *
@@ -13,8 +13,8 @@ export function MQOperationDecoratorFactory(decoratorChain, payloadType, options
13
13
  const operationMetadata = {
14
14
  kind: OpraSchema.MQOperation.Kind,
15
15
  channel: propertyKey,
16
- payloadType,
17
- ...omit(options, ['kind', 'payloadType']),
16
+ type,
17
+ ...omit(options, ['kind', 'type']),
18
18
  };
19
19
  const controllerMetadata = (Reflect.getOwnMetadata(MQ_CONTROLLER_METADATA, target.constructor) || {});
20
20
  controllerMetadata.operations = controllerMetadata.operations || {};
@@ -26,10 +26,10 @@ export function MQOperationDecoratorFactory(decoratorChain, payloadType, options
26
26
  /**
27
27
  *
28
28
  */
29
- decorator.UseType = (...type) => {
29
+ decorator.UseType = (...types) => {
30
30
  decoratorChain.push((meta) => {
31
31
  meta.types = meta.types || [];
32
- meta.types.push(...type);
32
+ meta.types.push(...types);
33
33
  });
34
34
  return decorator;
35
35
  };
@@ -44,6 +44,8 @@ export function MQOperationDecoratorFactory(decoratorChain, payloadType, options
44
44
  type: arg1,
45
45
  }
46
46
  : { ...arg1, name };
47
+ if (isConstructor(headerMetadata.type))
48
+ headerMetadata.designType = headerMetadata.type;
47
49
  const subMeta = inResponse ? meta.response : meta;
48
50
  if (subMeta.headers) {
49
51
  subMeta.headers = subMeta.headers.filter(p => String(p.name) !== String(name));
@@ -57,17 +59,19 @@ export function MQOperationDecoratorFactory(decoratorChain, payloadType, options
57
59
  /**
58
60
  *
59
61
  */
60
- decorator.Response = (_payloadType, _options) => {
62
+ decorator.Response = (_type, _options) => {
61
63
  decoratorChain.push((meta) => {
62
64
  inResponse = true;
63
65
  meta.response = {
64
66
  ..._options,
65
- payloadType: _payloadType,
67
+ type: _type,
66
68
  };
69
+ if (isConstructor(_type))
70
+ meta.response.designType = _type;
67
71
  });
68
72
  return decorator;
69
73
  };
70
- augmentationRegistry.forEach(fn => fn(decorator, decoratorChain, payloadType, options));
74
+ augmentationRegistry.forEach(fn => fn(decorator, decoratorChain, type, options));
71
75
  return decorator;
72
76
  }
73
77
  MQOperationDecoratorFactory.augment = function (fn) {
@@ -1,6 +1,6 @@
1
1
  import { merge } from '@jsopen/objects';
2
2
  import { OpraSchema } from '../../schema/index.js';
3
- import { MQ_CONTROLLER_METADATA } from '../constants.js';
3
+ import { WS_CONTROLLER_METADATA } from '../constants.js';
4
4
  const CLASS_NAME_PATTERN = /^(.*)(Controller)$/;
5
5
  const augmentationRegistry = [];
6
6
  export function WSControllerDecoratorFactory(options) {
@@ -13,10 +13,10 @@ export function WSControllerDecoratorFactory(options) {
13
13
  if (!name)
14
14
  name = CLASS_NAME_PATTERN.exec(target.name)?.[1] || target.name;
15
15
  const metadata = {};
16
- const baseMetadata = Reflect.getOwnMetadata(MQ_CONTROLLER_METADATA, Object.getPrototypeOf(target));
16
+ const baseMetadata = Reflect.getOwnMetadata(WS_CONTROLLER_METADATA, Object.getPrototypeOf(target));
17
17
  if (baseMetadata)
18
18
  merge(metadata, baseMetadata, { deep: true });
19
- const oldMetadata = Reflect.getOwnMetadata(MQ_CONTROLLER_METADATA, target);
19
+ const oldMetadata = Reflect.getOwnMetadata(WS_CONTROLLER_METADATA, target);
20
20
  if (oldMetadata)
21
21
  merge(metadata, oldMetadata, { deep: true });
22
22
  merge(metadata, {
@@ -25,10 +25,10 @@ export function WSControllerDecoratorFactory(options) {
25
25
  name,
26
26
  path: name,
27
27
  }, { deep: true });
28
- Reflect.defineMetadata(MQ_CONTROLLER_METADATA, metadata, target);
28
+ Reflect.defineMetadata(WS_CONTROLLER_METADATA, metadata, target);
29
29
  for (const fn of decoratorChain)
30
30
  fn(metadata, target);
31
- Reflect.defineMetadata(MQ_CONTROLLER_METADATA, metadata, target);
31
+ Reflect.defineMetadata(WS_CONTROLLER_METADATA, metadata, target);
32
32
  };
33
33
  /**
34
34
  *
@@ -1,8 +1,8 @@
1
1
  import { omit } from '@jsopen/objects';
2
2
  import { OpraSchema } from '../../schema/index.js';
3
- import { MQ_CONTROLLER_METADATA } from '../constants.js';
3
+ import { WS_CONTROLLER_METADATA } from '../constants.js';
4
4
  const augmentationRegistry = [];
5
- export function WSOperationDecoratorFactory(decoratorChain, payloadType, options) {
5
+ export function WSOperationDecoratorFactory(decoratorChain, options) {
6
6
  /**
7
7
  *
8
8
  */
@@ -11,16 +11,15 @@ export function WSOperationDecoratorFactory(decoratorChain, payloadType, options
11
11
  throw new TypeError(`Symbol properties can not be decorated`);
12
12
  const operationMetadata = {
13
13
  kind: OpraSchema.WSOperation.Kind,
14
- channel: propertyKey,
15
- payloadType,
16
- ...omit(options, ['kind', 'payloadType']),
14
+ event: propertyKey,
15
+ ...omit(options, ['kind']),
17
16
  };
18
- const controllerMetadata = (Reflect.getOwnMetadata(MQ_CONTROLLER_METADATA, target.constructor) || {});
17
+ const controllerMetadata = (Reflect.getOwnMetadata(WS_CONTROLLER_METADATA, target.constructor) || {});
19
18
  controllerMetadata.operations = controllerMetadata.operations || {};
20
19
  controllerMetadata.operations[propertyKey] = operationMetadata;
21
20
  for (const fn of decoratorChain)
22
21
  fn(operationMetadata, target, propertyKey);
23
- Reflect.defineMetadata(MQ_CONTROLLER_METADATA, controllerMetadata, target.constructor);
22
+ Reflect.defineMetadata(WS_CONTROLLER_METADATA, controllerMetadata, target.constructor);
24
23
  });
25
24
  /**
26
25
  *
@@ -32,7 +31,7 @@ export function WSOperationDecoratorFactory(decoratorChain, payloadType, options
32
31
  });
33
32
  return decorator;
34
33
  };
35
- augmentationRegistry.forEach(fn => fn(decorator, decoratorChain, payloadType, options));
34
+ augmentationRegistry.forEach(fn => fn(decorator, decoratorChain, options));
36
35
  return decorator;
37
36
  }
38
37
  WSOperationDecoratorFactory.augment = function (fn) {
@@ -0,0 +1,19 @@
1
+ import { WS_PARAM_METADATA } from '../constants.js';
2
+ export function WsParam(type) {
3
+ return (target, propertyKey, parameterIndex) => {
4
+ if (typeof propertyKey !== 'string')
5
+ throw new TypeError(`Un-named properties can not be decorated`);
6
+ if (!type) {
7
+ const designTypes = Reflect.getMetadata('design:paramtypes', target, propertyKey);
8
+ type = designTypes[parameterIndex];
9
+ if (!type)
10
+ throw new TypeError(`Missing parameter type`);
11
+ }
12
+ let paramMetadata = Reflect.getOwnMetadata(WS_PARAM_METADATA, target, propertyKey);
13
+ if (!paramMetadata) {
14
+ paramMetadata = [];
15
+ Reflect.defineMetadata(WS_PARAM_METADATA, paramMetadata, target, propertyKey);
16
+ }
17
+ paramMetadata[parameterIndex] = type;
18
+ };
19
+ }
@@ -9,6 +9,7 @@ import * as primitiveTypes 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
11
  import { MQApiFactory } from './mq-api.factory.js';
12
+ import { WSApiFactory } from './ws-api.factory.js';
12
13
  const OPRA_SPEC_URL = 'https://oprajs.com/spec/v' + OpraSchema.SpecVersion;
13
14
  /**
14
15
  * @class ApiDocumentFactory
@@ -127,6 +128,14 @@ export class ApiDocumentFactory {
127
128
  if (api)
128
129
  document.api = api;
129
130
  }
131
+ else if (init.api && init.api.transport === 'ws') {
132
+ const api = await WSApiFactory.createApi(context, {
133
+ ...init.api,
134
+ owner: document,
135
+ });
136
+ if (api)
137
+ document.api = api;
138
+ }
130
139
  else
131
140
  context.addError(`Unknown service transport (${init.api.transport})`);
132
141
  });
@@ -2,6 +2,7 @@ import { cloneObject, resolveThunk, ResponsiveMap, } from '../../helpers/index.j
2
2
  import { OpraSchema } from '../../schema/index.js';
3
3
  import { DocumentInitContext } from '../common/document-init-context.js';
4
4
  import { DATATYPE_METADATA, DECODER, ENCODER, kCtorMap, kDataTypeMap, } from '../constants.js';
5
+ import { ArrayType } from '../data-type/array-type.js';
5
6
  import { ComplexType } from '../data-type/complex-type.js';
6
7
  import { ComplexTypeBase } from '../data-type/complex-type-base.js';
7
8
  import { DataType } from '../data-type/data-type.js';
@@ -248,6 +249,9 @@ export class DataTypeFactory {
248
249
  }
249
250
  }
250
251
  switch (out.kind) {
252
+ case OpraSchema.ArrayType.Kind:
253
+ await this._prepareArrayTypeArgs(context, owner, out, metadata);
254
+ break;
251
255
  case OpraSchema.ComplexType.Kind:
252
256
  out.ctor = ctor;
253
257
  await this._prepareComplexTypeArgs(context, owner, out, metadata);
@@ -288,6 +292,15 @@ export class DataTypeFactory {
288
292
  initArgs.examples = metadata.examples;
289
293
  initArgs.scopePattern = metadata.scopePattern;
290
294
  }
295
+ static async _prepareArrayTypeArgs(context, owner, initArgs, metadata) {
296
+ await this._prepareDataTypeArgs(context, initArgs, metadata);
297
+ await context.enterAsync('.type', async () => {
298
+ const baseArgs = await this._importDataTypeArgs(context, owner, metadata.type);
299
+ if (!baseArgs)
300
+ return;
301
+ initArgs.type = preferName(baseArgs);
302
+ });
303
+ }
291
304
  static async _prepareComplexTypeArgs(context, owner, initArgs, metadata) {
292
305
  await this._prepareDataTypeArgs(context, initArgs, metadata);
293
306
  initArgs.keyField = metadata.keyField;
@@ -468,6 +481,8 @@ export class DataTypeFactory {
468
481
  dataTypeMap.set(dataType.name, dataType);
469
482
  }
470
483
  switch (initArgs?.kind) {
484
+ case OpraSchema.ArrayType.Kind:
485
+ return this._createArrayType(context, owner, initArgs);
471
486
  case OpraSchema.ComplexType.Kind:
472
487
  return this._createComplexType(context, owner, initArgs);
473
488
  case OpraSchema.EnumType.Kind:
@@ -486,6 +501,18 @@ export class DataTypeFactory {
486
501
  }
487
502
  context.addError(`Unknown data type (${String(args)})`);
488
503
  }
504
+ static _createArrayType(context, owner, args) {
505
+ const dataType = args._instance || {};
506
+ Object.setPrototypeOf(dataType, ArrayType.prototype);
507
+ const initArgs = cloneObject(args);
508
+ if (args.type) {
509
+ context.enter('.type', () => {
510
+ initArgs.type = this._createDataType(context, owner, args.type);
511
+ });
512
+ }
513
+ ArrayType.apply(dataType, [owner, initArgs]);
514
+ return dataType;
515
+ }
489
516
  static _createComplexType(context, owner, args) {
490
517
  const dataType = args._instance || {};
491
518
  Object.setPrototypeOf(dataType, ComplexType.prototype);
@@ -113,7 +113,7 @@ export class MQApiFactory {
113
113
  ...operationMeta,
114
114
  name: operationName,
115
115
  types: undefined,
116
- payloadType: undefined,
116
+ type: undefined,
117
117
  keyType: undefined,
118
118
  });
119
119
  await this._initMQOperation(context, operation, operationMeta);
@@ -137,7 +137,7 @@ export class MQApiFactory {
137
137
  await DataTypeFactory.addDataTypes(context, operation, metadata.types);
138
138
  });
139
139
  }
140
- operation.payloadType = await DataTypeFactory.resolveDataType(context, operation, metadata.payloadType);
140
+ operation.type = await DataTypeFactory.resolveDataType(context, operation, metadata.type);
141
141
  if (metadata.keyType) {
142
142
  operation.keyType = await DataTypeFactory.resolveDataType(context, operation, metadata.keyType);
143
143
  }
@@ -160,7 +160,7 @@ export class MQApiFactory {
160
160
  await context.enterAsync('.response', async () => {
161
161
  const response = new MQOperationResponse(operation, {
162
162
  ...metadata.response,
163
- payloadType: undefined,
163
+ type: undefined,
164
164
  keyType: undefined,
165
165
  });
166
166
  await this._initMQOperationResponse(context, response, metadata.response);
@@ -176,7 +176,7 @@ export class MQApiFactory {
176
176
  * @protected
177
177
  */
178
178
  static async _initMQOperationResponse(context, response, metadata) {
179
- response.payloadType = await DataTypeFactory.resolveDataType(context, response, metadata.payloadType);
179
+ response.type = await DataTypeFactory.resolveDataType(context, response, metadata.type);
180
180
  if (metadata.keyType) {
181
181
  response.keyType = await DataTypeFactory.resolveDataType(context, response, metadata.keyType);
182
182
  }
@@ -1,6 +1,6 @@
1
1
  import { isConstructor } from '@jsopen/objects';
2
2
  import { resolveThunk } from '../../helpers/index.js';
3
- import { WS_CONTROLLER_METADATA } from '../constants.js';
3
+ import { WS_CONTROLLER_METADATA, WS_PARAM_METADATA } from '../constants.js';
4
4
  import { WSApi } from '../ws/ws-api.js';
5
5
  import { WSController } from '../ws/ws-controller.js';
6
6
  import { WSOperation } from '../ws/ws-operation.js';
@@ -84,17 +84,26 @@ export class WSApiFactory {
84
84
  }
85
85
  if (metadata.operations) {
86
86
  await context.enterAsync('.operations', async () => {
87
- for (const [operationName, operationMeta] of Object.entries(metadata.operations)) {
87
+ for (const [operationName, _operationMeta] of Object.entries(metadata.operations)) {
88
88
  await context.enterAsync(`[${operationName}]`, async () => {
89
+ const argumentsMetadata = Reflect.getMetadata(WS_PARAM_METADATA, ctor.prototype, operationName);
90
+ let operationMeta = _operationMeta;
91
+ if (argumentsMetadata) {
92
+ operationMeta = {
93
+ ...operationMeta,
94
+ arguments: argumentsMetadata,
95
+ };
96
+ }
89
97
  const operation = new WSOperation(controller, {
90
98
  ...operationMeta,
91
99
  name: operationName,
92
100
  types: undefined,
93
- payloadType: undefined,
101
+ type: undefined,
94
102
  keyType: undefined,
103
+ arguments: undefined,
95
104
  });
96
105
  await this._initWSOperation(context, operation, operationMeta);
97
- controller.operations.set(operation.name, operation);
106
+ controller.operations.set(operationName, operation);
98
107
  });
99
108
  }
100
109
  });
@@ -114,6 +123,19 @@ export class WSApiFactory {
114
123
  await DataTypeFactory.addDataTypes(context, operation, metadata.types);
115
124
  });
116
125
  }
117
- operation.payloadType = await DataTypeFactory.resolveDataType(context, operation, metadata.payloadType);
126
+ if (metadata.arguments?.length) {
127
+ await context.enterAsync('.arguments', async () => {
128
+ operation.arguments = [];
129
+ for (const x of metadata.arguments) {
130
+ const t = await DataTypeFactory.resolveDataType(context, operation, x);
131
+ operation.arguments?.push(t);
132
+ }
133
+ });
134
+ }
135
+ if (metadata.response) {
136
+ await context.enterAsync('.response', async () => {
137
+ operation.response = await DataTypeFactory.resolveDataType(context, operation, metadata.response);
138
+ });
139
+ }
118
140
  }
119
141
  }
@@ -3,6 +3,7 @@ import { omitUndefined } from '@jsopen/objects';
3
3
  import { asMutable } from 'ts-gems';
4
4
  import { isAny, vg } from 'valgen';
5
5
  import { DocumentElement } from '../common/document-element.js';
6
+ import { ArrayType } from '../data-type/array-type.js';
6
7
  import { DataType } from '../data-type/data-type.js';
7
8
  export const HttpMediaType = function (owner, initArgs) {
8
9
  if (!this)
@@ -32,6 +33,7 @@ export const HttpMediaType = function (owner, initArgs) {
32
33
  : _this.owner.node.getDataType(initArgs.type);
33
34
  }
34
35
  _this.isArray = initArgs.isArray;
36
+ _this.designType = initArgs.designType;
35
37
  };
36
38
  /**
37
39
  * @class HttpMediaType
@@ -71,21 +73,28 @@ class HttpMediaTypeClass extends DocumentElement {
71
73
  }
72
74
  return out;
73
75
  }
74
- generateCodec(codec, options) {
76
+ generateCodec(codec, options, properties) {
75
77
  let fn;
76
78
  if (this.type) {
77
- fn = this.type.generateCodec(codec, options);
79
+ fn = this.type.generateCodec(codec, options, {
80
+ designType: this.designType,
81
+ });
78
82
  }
79
83
  else if (this.contentType) {
80
84
  const arr = Array.isArray(this.contentType)
81
85
  ? this.contentType
82
86
  : [this.contentType];
83
87
  if (arr.find(ct => typeIs.is(ct, ['json']))) {
84
- fn = this.node.findDataType('object').generateCodec(codec);
88
+ fn = this.node.findDataType('object').generateCodec(codec, options, {
89
+ ...properties,
90
+ designType: this.designType,
91
+ });
85
92
  }
86
93
  }
87
94
  fn = fn || isAny;
88
- return this.isArray ? vg.isArray(fn) : fn;
95
+ return this.isArray && !(this.type instanceof ArrayType)
96
+ ? vg.isArray(fn)
97
+ : fn;
89
98
  }
90
99
  }
91
100
  HttpMediaType.prototype = HttpMediaTypeClass.prototype;
@@ -1,5 +1,6 @@
1
1
  import { omitUndefined } from '@jsopen/objects';
2
2
  import { asMutable, } from 'ts-gems';
3
+ import { vg } from 'valgen';
3
4
  import { Value } from '../common/value.js';
4
5
  import { parseRegExp } from '../utils/parse-regexp.util.js';
5
6
  export const HttpParameter = function (owner, initArgs) {
@@ -26,6 +27,7 @@ export const HttpParameter = function (owner, initArgs) {
26
27
  _this.arraySeparator = initArgs.arraySeparator;
27
28
  _this.keyParam = initArgs.keyParam;
28
29
  _this.parser = initArgs.parser;
30
+ _this.designType = initArgs.designType;
29
31
  };
30
32
  /**
31
33
  * @class HttpParameter
@@ -42,5 +44,11 @@ class HttpParameterClass extends Value {
42
44
  deprecated: this.deprecated,
43
45
  });
44
46
  }
47
+ generateCodec(codec, options, properties) {
48
+ return (this.type?.generateCodec(codec, options, {
49
+ ...properties,
50
+ designType: this.designType,
51
+ }) || vg.isAny());
52
+ }
45
53
  }
46
54
  HttpParameter.prototype = HttpParameterClass.prototype;
@@ -23,6 +23,7 @@ export * from './common/document-node.js';
23
23
  export * from './common/opra-document-error.js';
24
24
  export * from './constants.js';
25
25
  export * from './data-type/api-field.js';
26
+ export * from './data-type/array-type.js';
26
27
  export * from './data-type/complex-type.js';
27
28
  export * from './data-type/data-type.js';
28
29
  export * from './data-type/enum-type.js';
@@ -36,6 +37,7 @@ export * from './data-type/primitive-types/index.js';
36
37
  export * from './data-type/required-type.js';
37
38
  export * from './data-type/simple-type.js';
38
39
  export * from './data-type/union-type.js';
40
+ export * from './decorators/ws-param.decorator.js';
39
41
  export * from './factory/api-document.factory.js';
40
42
  export * from './http/http-api.js';
41
43
  export * from './http/http-controller.js';
@@ -1,5 +1,6 @@
1
1
  import { omitUndefined } from '@jsopen/objects';
2
2
  import { asMutable, } from 'ts-gems';
3
+ import { vg } from 'valgen';
3
4
  import { Value } from '../common/value.js';
4
5
  import { parseRegExp } from '../utils/parse-regexp.util.js';
5
6
  export const MQHeader = function (owner, initArgs) {
@@ -20,6 +21,7 @@ export const MQHeader = function (owner, initArgs) {
20
21
  }
21
22
  _this.deprecated = initArgs.deprecated;
22
23
  _this.required = initArgs.required;
24
+ _this.designType = initArgs.designType;
23
25
  };
24
26
  /**
25
27
  * @class MQHeader
@@ -33,5 +35,11 @@ class MQHeaderClass extends Value {
33
35
  deprecated: this.deprecated,
34
36
  });
35
37
  }
38
+ generateCodec(codec, options, properties) {
39
+ return (this.type?.generateCodec(codec, options, {
40
+ ...properties,
41
+ designType: this.designType,
42
+ }) || vg.isAny());
43
+ }
36
44
  }
37
45
  MQHeader.prototype = MQHeaderClass.prototype;
@@ -10,20 +10,22 @@ export class MQOperationResponse extends DocumentElement {
10
10
  this.headers = [];
11
11
  this.channel = initArgs?.channel;
12
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);
13
+ if (initArgs?.type) {
14
+ this.type =
15
+ initArgs?.type instanceof DataType
16
+ ? initArgs.type
17
+ : this.owner.node.getDataType(initArgs.type);
18
18
  }
19
19
  else
20
- this.payloadType = this.owner.node.getDataType('any');
20
+ this.type = this.owner.node.getDataType('any');
21
21
  if (initArgs?.keyType) {
22
22
  this.keyType =
23
23
  initArgs?.keyType instanceof DataType
24
24
  ? initArgs.keyType
25
25
  : this.owner.node.getDataType(initArgs.keyType);
26
26
  }
27
+ this.designType = initArgs?.designType;
28
+ this.keyDesignType = initArgs?.keyDesignType;
27
29
  }
28
30
  findHeader(paramName) {
29
31
  const paramNameLower = paramName.toLowerCase();
@@ -42,9 +44,7 @@ export class MQOperationResponse extends DocumentElement {
42
44
  const out = omitUndefined({
43
45
  description: this.description,
44
46
  channel: this.channel,
45
- payloadType: this.payloadType.name
46
- ? this.payloadType.name
47
- : this.payloadType.toJSON(),
47
+ type: this.type.name ? this.type.name : this.type.toJSON(),
48
48
  keyType: this.keyType
49
49
  ? this.keyType.name
50
50
  ? this.keyType.name